如何解决以编程方式确定变量的值是在编译时还是在运行时计算的
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 @Nate Eldredge notes是GCC和Clang中的内置函数__builtin_constant_p()
。
以下是相关摘录from the GCC doc:
内置函数:
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.
}
}
使用您自己的示例:
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));
,
你问
C中是否有一种方法可以通过编程确定该变量的 值是在编译时还是在运行时计算的?
不,无法将这种确定编码为严格符合标准的C程序的源代码。
当然,C不需要以对值进行区分的方式对值进行系统地标记,并且我从没听说过或想到过C的实现方式,因此,这种确定不能基于感兴趣的表达式的值。此外,所有C函数参数都按值传递,因此假设的compute_time()
不能实现为函数,因为值是所有必须使用的值。
compute_time()
也不能是宏,因为宏只能用于(预处理)令牌,例如,示例中的标识符c1
和c2
码。这些对于预处理器是不透明的;当根据C语义将它们作为表达式求值时,它对归于它们的值一无所知。
并且没有用于此目的的运算符。
标准C没有提供其他替代方法,因此,如果问题是关于C语言的,而不是有关C语言的任何特定实现的,那么这就是故事的结尾。而且,尽管可以想象给定的C实现将提供您的compute_time()
或功能等效的扩展名,但我不知道有任何实现。 (但是,请参见@MarcoBonelli's answer,以获取类似但不相同的扩展名的示例。)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。