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

Programmatically determine if a variable's value was computed at compile time or at run time

在 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);

在C中(as in,由语言标准定义),不行,没办法。

然而,有 compiler-specific 种方法可以让您真正接近实现您想要的目标。评论中最著名的 是 GCC 和 Clang 中可用的内置函数 __builtin_constant_p()

这里是相关的摘录from the GCC doc

Built-in Function: int __builtin_constant_p (exp)

You can use the built-in function __builtin_constant_p to determine if a value is known to be constant at compile time and hence that GCC can perform constant-folding on expressions involving that value. The argument of the function is the value to test. The function returns the integer 1 if the argument is known to be a compile-time constant and 0 if it is not known to be a compile-time constant. A return of 0 does not indicate that the value is not a constant, but merely that GCC cannot prove it is a constant with the specified value of the -O option.

注意这个函数不能保证检测到所有compile-time常量,但只能检测GCC能够检测到的常量证明如此。不同的优化级别可能会改变此函数返回的结果。

此 built-in 函数在 glibc 中广泛用于优化目的 (example),通常结果仅在其为 1 时才可信,否则假设为 non-constant:

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.
    }
}

使用你自己的例子:

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));

你问,

Is there a way in C to programmatically determine that variable's value was computed at compile time or at run time?

不,没有办法将这样的决定编码到严格符合 C 程序的源代码中。

当然,C 不要求系统地标记值,以根据它们的计算时间来区分它们,而且我听说过或想象过的 C 实现都没有这样做,所以这样的决定不能基于关于兴趣表达的价值。此外,所有 C 函数参数都是按值传递的,因此假设的 compute_time() 不能作为函数实现,因为它必须使用值。

compute_time() 也不能是宏,因为宏只能用于(预处理)tokens,例如标识符 c1c2 在您的示例代码中。这些对预处理器是不透明的;当根据 C 语义将它们评估为表达式时,它对赋予它们的值一无所知。

并且没有符合此目的的运算符。

标准 C 没有提供其他选择,因此如果问题是关于 C 语言而不是它的任何特定实现,那么故事就到此为止。此外,尽管可以想象给定的 C 实现会提供您的 compute_time() 或等效的功能作为扩展,但我不知道有任何这样的实现。 (但是,请参阅 ,了解类似但不完全相同的扩展示例。)