如何确保 constexpr 函数在运行时不会被调用?

2024-02-04

假设您有一个函数可以为您的应用程序生成一些安全令牌,例如一些哈希盐,或者可能是对称或非对称密钥。

现在假设您在 C++ 中将此函数作为 constexpr,并且您根据某些信息(例如构建号、时间戳等)为构建生成密钥。

作为一名勤奋的程序员,请确保以适当的方式调用它,以确保它仅在编译时调用,因此死剥离器会从最终的可执行文件中删除代码。

但是,您永远无法确定其他人不会以不安全的方式调用它,或者编译器可能不会删除该函数,然后您的安全令牌算法将成为公众知识,使其成为可能攻击者更容易猜测未来的代币。

或者,除了安全性之外,假设该函数需要很长时间才能执行,并且您希望确保它不会在运行时发生并给最终用户带来不良的用户体验。

有没有什么方法可以确保 constexpr 函数永远不会在运行时被调用?或者,在运行时抛出断言或类似的东西也可以,但显然不如编译错误那么理想。

我听说有某种方法涉及抛出不存在的异常类型,因此如果 constexpr 函数没有被完全删除,您将收到链接器错误,但听说这仅适用于某些编译器。

遥远相关的问题:强制 constexpr 在编译时求值 https://stackoverflow.com/questions/24322386/force-constexpr-to-be-evaluated-at-compile-time


In C++20你可以更换constexpr by consteval强制函数始终在编译时求值。

Example:

          int    rt_function(int v){ return v; }
constexpr int rt_ct_function(int v){ return v; }
consteval int    ct_function(int v){ return v; }

int main(){
    constexpr int ct_value = 1; // compile value
    int           rt_value = 2; // runtime value

    int a = rt_function(ct_value);
    int b = rt_ct_function(ct_value);
    int c = ct_function(ct_value);

    int d = rt_function(rt_value);
    int e = rt_ct_function(rt_value);
    int f = ct_function(rt_value); // ERROR: runtime value

    constexpr int g = rt_function(ct_value); // ERROR: runtime function
    constexpr int h = rt_ct_function(ct_value);
    constexpr int i = ct_function(ct_value);
}

C++20 之前的解决方法

您可以强制在常量表达式中使用它:

#include<utility>

template<typename T, T V>
constexpr auto ct() { return V; }

template<typename T>
constexpr auto func() {
    return ct<decltype(std::declval<T>().value()), T{}.value()>();
}

template<typename T>
struct S {
    constexpr S() {}
    constexpr T value() { return T{}; }
};

template<typename T>
struct U {
    U() {}
    T value() { return T{}; }
};

int main() {
    func<S<int>>();
    // won't work
    //func<U<int>>();
}

通过使用函数的结果作为模板参数,如果无法在编译时解决,则会出现错误。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何确保 constexpr 函数在运行时不会被调用? 的相关文章

随机推荐