W.F*_*.F. 4 c++ short-circuiting language-lawyer constant-expression
考虑示例:
template <char>
struct foo { };
int main() {
foo<""[0]?""[1]:'\0'>{};
}
Run Code Online (Sandbox Code Playgroud)
代码在[gcc]和[clang]中编译,但它应该真的吗?我知道表达式""[1]
不需要进行评估,因为它是短路的.但是,如果表达式实际上可以作为核心常量表达式,则标准不是很清楚.相关[expr.const]/2,尤其是部分:
如果e满足核心常量表达式的约束,但e的评估将评估具有本文档的[library]至[thread]中指定的未定义行为的操作,则未指定e是否是核心常量表达式.
引起我的怀疑......
我相信提取物实际上涵盖了:
如果
e
满足一个芯常量表达式的约束,但电子商务的评价将评估已未定义的行为的动作如指定的在[library]
通过[thread]
本文件,它是未指定的是否e
是一个核心常量表达式.
表达式中实际上没有未定义的行为,""[0]?""[1]:'\0'
因为唯一有问题的位""[1]
从未实际执行过.事实上,整个表达式可以简单地优化到'\0'
没有不利影响.
它未被执行的原因来自标准本身(例如C++11 5.16 Conditional operator [expr.cond] /1
:
条件表达式从右到左分组.第一个表达式在上下文中转换为
bool
(第4条).它被评估,如果是,则条件表达式的结果是第二个表达式的值,否则是第三个表达式的值.仅评估第二和第三表达式中的一个.
由于""[0]
在布尔上下文中将始终求值为false,因此永远不会执行第二个子表达式.它与表达式在概念上没有任何区别:
false ? (1/0) : 42
Run Code Online (Sandbox Code Playgroud)
因为你永远不必担心被零除的可能性.