我知道ISO C标准在区分翻译行为和执行行为方面做了很多工作,部分原因是为了确保交叉编译器不必携带每个目标的执行环境。
我的意思是,与运行中的程序相比,编译器可获得的信息有限。这限制了您在源代码中可以做的事情,例如不根据函数的返回值初始化变量,如下所示:
int twice (int val) { return val * 2; }
int xyzzy = twice (7);
int main () { printf ("%dn", xyzzy); return 0; }
我好奇的是c++ 11中的用户定义字面值是如何适应这种模式的。由于文字求值依赖于一个函数,如何阻止该函数做如下事情:
- 返回一个随机值(即使基于输入,如
42_roughly
给你40和44之间的值)? - 有副作用,比如改变全局变量?
必须调用函数的事实是否意味着这些在编译时计算的意义上不是真正的字面量?
如果是这样的话,这些字面值与其他函数调用相比有什么优势?换句话说,为什么是:
int xyzzy = 1101_1110_b;
比:
int xyzzy = makeBin ("1101_1110");
?
关键在于是否将用户定义的文字函数声明为constexpr
。
比较这个(正常的执行时间函数):
#include <iostream>
int operator "" _twice(unsigned long long num) { return num*2; }
int xyzzy = 7_twice;
int main () { std::cout << xyzzy << "n"; return 0; }
使用这个(编译时常量,static_assert
工作):
#include <iostream>
constexpr int operator "" _twice(unsigned long long num) { return num*2; }
int xyzzy = 7_twice;
int main () {
static_assert(7_twice == 14, "not compile time constant");
std::cout << xyzzy << "n";
return 0;
}
显然,声明一个函数constexpr
限制了其中的所有语句也都是constexpr
,或者是编译时常量;