Consider example:
template <char>
struct foo { };
int main() {
foo<""[0]?""[1]:'\0'>{};
}
The code compiles in both [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 and especially part:
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.
raises my doubts...
I believe the extract actually covers that:
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 whethere
is a core constant expression.
There is actually no undefined behaviour in the expression ""[0]?""[1]:'\0'
because the only problematic bit ""[1]
is never actually executed. In fact, the entire expression can simply be optimised to '\0'
without adverse effects.
The reason it's not executed comes from the standard itself (e.g., 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.
Since ""[0]
will always evaluate to false in the boolean context, the second sub-expression is never executed. It's really no conceptually different from the expression:
false ? (1/0) : 42
in that you'll never actually have to worry about the possibility of divide-by-zero.
To answer that, one would have to quote the start of this paragraph, which says:
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:
And since the rules of the abstract machine promise the evaluation of the out of bounds access won't happen ([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.
There's no undefined behavior, so it must be a core constant expression. Or at least, it's not the bullet you quoted which disqualifies it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With