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

Viewed 270

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

Example:

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

In C (as in, defined by the language standard), no, there is no way.

There are however compiler-specific ways using which you can get really close to achieving what you want. The most famous, as @Nate Eldredge notes in the comments, is the builtin function __builtin_constant_p() available in GCC and Clang.

Here's the relevant excerpt 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.

Note that this function does not guarantee to detect all compile-time constants, but only the ones that GCC is able to prove as such. Different optimization levels might change the result returned by this function.

This built-in function is widely used in glibc for optimization purposes (example), and usually the result is only trusted when it's 1, assuming a non-constant otherwise:

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

Using your own example:

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

You ask,

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

No, there is no way to encode such a determination into the source of a strictly conforming C program.

Certainly C does not require values to be tagged systematically in a way that distinguishes among them based on when they were computed, and no C implementation I have ever heard of or imagined does that, so such a determination cannot be based on the values of the expressions of interest. Furthermore, all C function arguments are passed by value, so the hypothetical compute_time() cannot be implemented as a function because values are all it would have to work with.

compute_time() also cannot be a macro, because macros can work only with (preprocessing) tokens, for example the identifiers c1 and c2 in your example code. Those are opaque to the preprocessor; it knows nothing about values attributed to them when they are evaluated as expressions according to C semantics.

And there is no operator that serves the purpose.

Standard C provides no other alternatives, so if the question is about the C language and not any particular implementation of it then that's the end of the story. Moreover, although it is conceivable that a given C implementation would provide your compute_time() or a functional equivalent as an extension, I am unaware of any that do. (However, see @MarcoBonelli's answer, for an example of a similar, but not identical, extension.)

Related