当短路禁用其评估时,是否允许在常量表达式中读取一个结束指针

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是否是核心常量表达式.

引起我的怀疑......

pax*_*blo 6

我相信提取物实际上涵盖了:

如果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)

因为你永远不必担心被零除的可能性.