静态变量地址可作为constexpr使用的行为是否为C++标准强制要求?
静态变量地址可作为constexpr使用的行为是否为C++标准强制要求?
没错,这个行为确实是C++标准强制要求的,咱们一步步拆解你遇到的几种情况,就能明白标准的规则:
为什么第一个例子无法编译?
看这段代码:int main() { constexpr int i = 0; constexpr const int* ptr = &i; }这里的
i是非静态的局部变量,哪怕它被标记为constexpr,它的存储空间还是在main函数的栈帧里。C++标准明确规定:非静态局部对象的地址不能作为编译期常量表达式——虽然这个例子里编译器理论上能"猜"出地址,但标准不允许这种情况,因为栈帧的位置本质上是程序运行时才会分配的,没有固定的编译期地址。为什么全局constexpr变量的地址可以用在constexpr里?
这段能编译的代码:constexpr int i = 0; int main() { constexpr const int* r = &i; }这里的
i是全局变量,它存在于程序的静态存储区,它的地址在编译阶段就已经被确定下来了,完全符合constexpr对编译期常量的要求,所以标准允许把它的地址用来初始化constexpr指针。为什么静态局部constexpr变量也可以?
再看这段代码:int main() { static constexpr int i = 0; constexpr const int* r = &i; }静态局部变量
i的存储空间同样在静态存储区,和全局变量一样,它的地址在编译时就能被确定,所以标准也允许把它的地址作为constexpr值来使用。
总结一下:C++标准对常量表达式的定义里,明确将静态存储期对象的地址(包括指向这类对象的指针操作)纳入了合法范围,而非静态局部对象的地址则被排除在外,所以你遇到的这些编译结果都是标准强制要求的,不是某个编译器的特殊行为。
备注:内容来源于stack exchange,提问作者dwto
相关产品推荐
相关产品推荐

