C++常量求值读取生命周期外变量是否必须诊断为错误
C++常量求值中读取超生命周期变量是否必须触发编译失败
问题背景
测试代码如下:
constexpr bool g() { int * p = nullptr; { int c = 0; p = &c; } return *p == 0; }; int main() { static_assert( g() ); }
测试现象:
- Clang编译时直接报错:
read of object outside its lifetime is not allowed in a constant expression - GCC会静默编译通过该程序
结论
GCC的处理不符合C++标准要求,该代码属于明确的非法常量表达式,所有符合标准的编译器都必须拒绝编译。
标准依据
C++标准明确规定,常量表达式求值过程中不允许出现以下操作:
- 解引用悬空指针
- 访问生命周期已经结束的对象的值
上述代码中,局部变量c的生命周期在内部代码块结束时就已经终止,后续*p是对指向已销毁对象的悬空指针做解引用访问,属于标准明确禁止在常量表达式中出现的操作,这类错误不属于实现可选择处理的范畴,编译器必须出具诊断信息,拒绝编译。
GCC当前的放行行为是已知的编译器缺陷,而非标准允许的实现差异。
内容的提问来源于stack exchange,提问作者Fedor
相关产品推荐
相关产品推荐

