我正在研究核心常量表达式*中允许的内容,这在C++标准草案的5.19 常量表达式第2段中有所描述:
条件表达式是核心常量表达式,除非它涉及以下之一作为潜在评估的子表达式(3.2),但是未评估的逻辑AND(5.14),逻辑OR(5.15)和条件(5.16)操作的子表达式不考虑[注意:重载的运算符调用函数.-end note]:
并列出随后的子弹中的排除项并包括(强调我的):
- 具有未定义行为的操作 [注意:包括,例如,有符号整数溢出(第5条),某些指针算术(5.7),除零(5.6)或某些移位操作(5.8) - 结束注释];
嗯?为什么常量表达式需要此子句来涵盖未定义的行为?常量表达式是否有一些特殊的东西需要未定义的行为才能在排除中进行特殊划分?
拥有这个条款是否给了我们没有它的任何优势或工具?
作为参考,这看起来像广义常量表达式提案的最新修订版.
以下代码调用未定义的行为.
int& foo()
{
int bar = 1234;
return bar;
}
Run Code Online (Sandbox Code Playgroud)
g ++发出警告:
警告:返回对局部变量'bar'的引用[-Wreturn-local-addr]
clang ++也是:
警告:返回与本地变量'bar'关联的堆栈内存[-Wreturn-stack-address]
为什么这不是编译错误(忽略-Werror)?
是否存在将ref返回到本地var的情况?
编辑正如所指出的,规范要求这是可编译的.那么,为什么规范不禁止这样的代码呢?