当短路禁用其评估时,正在读取常量表达式中允许的尾数指针

Is reading one-past-the-end pointer allowed in a constant expression when short-circuit disable its evaluation

考虑示例:

template <char>
struct foo { };

int main() {
    foo<""[0]?""[1]:'[=10=]'>{};
}

代码在 [gcc] and [clang], but should it really? I know the expression ""[1] doesn't need to be evaluated as it was short-circuited. But standard isn't very clear if the expression can actually qualify as a core constant expression. Relevant [expr.const]/2 中编译,尤其是部分:

If e satisfies the constraints of a core constant expression, but evaluation of e would evaluate an operation that has undefined behavior as specified in [library] through [thread] of this document, it is unspecified whether e is a core constant expression.

引起我的怀疑...

我相信摘录实际上涵盖了:

If e satisfies the constraints of a core constant expression, but evaluation of e would evaluate an operation that has undefined behaviour as specified in [library] through [thread] of this document, it is unspecified whether e is a core constant expression.

在表达式 ""[0]?""[1]:'[=15=]' 中实际上 没有 未定义的行为,因为唯一有问题的位 ""[1] 永远不会 实际上 执行。事实上,整个表达式可以简单地优化为 '[=17=]' 而不会产生不利影响。

未执行的原因来自标准本身(例如,C++11 5.16 Conditional operator [expr.cond] /1:

Conditional expressions group right-to-left. The first expression is contextually converted to bool (Clause 4). It is evaluated and if it is true, the result of the conditional expression is the value of the second expression, otherwise that of the third expression. Only one of the second and third expressions is evaluated.

由于 ""[0] 在布尔上下文中总是计算为 false,因此永远不会执行第二个子表达式。它在概念上与表达式没有什么不同:

false ? (1/0) : 42

因为您实际上永远不必担心被零除的可能性。

要回答这个问题,必须引用本段的开头,其中说:

An expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine, would evaluate one of the following expressions:

并且由于抽象机的规则承诺不会发生越界访问的评估 ([expr.cond]/1):

Conditional expressions group right-to-left. The first expression is contextually converted to bool. It is evaluated and if it is true, the result of the conditional expression is the value of the second expression, otherwise that of the third expression. Only one of the second and third expressions is evaluated.

没有未定义的行为,所以它必须是核心常量表达式。或者至少,不是您引用的项目符号使它不合格。