以编程方式确定变量的值是在编译时还是在运行时计算的

Pav*_*kin 3 c constants

在 C 中有没有办法以编程方式确定变量的值是在编译时还是在运行时计算的?

例子:

const double a = 2.0;
const double b = 3.0;
double c1 = a / b; // done at compile time (constant folding / propagation)
double c2 = *(volatile double*)&a / *(volatile double*)&b; // done at run time
compute_time_t c1_ct = compute_time(c1);
compute_time_t c2_ct = compute_time(c2);
assert(c1_ct == COMPILE_TIME);
assert(c2_ct == RUN_TIME);
Run Code Online (Sandbox Code Playgroud)

Mar*_*lli 6

在 C 中(如在,由语言标准定义),不,没有办法。

然而,有一些特定于编译器的方法可以让您真正接近实现您想要的目标。正如@Nate Eldredge在评论中指出的那样,最著名的是__builtin_constant_p()GCC 和 Clang 中可用的内置函数。

以下是GCC 文档的相关摘录:

内置功能: int __builtin_constant_p (exp)

您可以使用内置函数__builtin_constant_p来确定某个值在编译时是否已知为常量,因此 GCC 可以对涉及该值的表达式执行常量折叠。函数的参数是要测试的值。如果参数已知是编译时常量,则函数返回整数 1,如果不知道它是编译时常量,则返回整数 0。返回 0 并不表示该值不是常量,而只是 GCC 无法证明它是具有指定-O选项值的常量。

请注意,此函数不能保证检测所有编译时常量,而只能检测GCC 能够证明的那些。不同的优化级别可能会改变此函数返回的结果。

这个内置函数在 glibc 中被广泛用于优化目的(example),通常结果只在它为 1 时才可信,否则假设为非常量:

void somefunc(int x) {
    if (__builtin_constant_p(x)) {
        // Perform optimized operation knowing x is a compile-time constant.
    } else {
        // Assume x is not a compile-time constant.
    }
}
Run Code Online (Sandbox Code Playgroud)

使用您自己的示例:

const double a = 2.0;
const double b = 3.0;
double c1 = a / b; // done at compile time (constant folding / propagation)
double c2 = *(volatile double*)&a / *(volatile double*)&b; // done at run time

assert(__builtin_constant_p(c1));
assert(!__builtin_constant_p(c2));
Run Code Online (Sandbox Code Playgroud)