Open frederick-vs-ja opened 2 weeks ago
[expr.unary.op] p7 says "Integral promotion is performed on integral or enumeration operands."
So, we're promoting (erroneous) char to (erroneous) int. That latter part triggers erroneous behavior per [basic.indet] p2. And that, in turn, triggers [expr.const] p5.8. Your example is not a constant expression.
I'm not seeing a defect.
Oops, the original example was wrong.
A corrected example might be:
static_assert([]{
unsigned char c; // the value is indeterminate until C++26, erroneous since C++26
static_cast<unsigned char>(c);
return true;
}());
Full name of submitter (unless configured in github; will be published with the issue): Jiang An
Reference (section label): [expr.const]
Link to reflector thread (if any):
Issue description:
Split from https://github.com/cplusplus/CWG/issues/550#issuecomment-2167114295. It seems that the following example should still be rejected after P2795R5.
Originally posted wrong example
```C++ static_assert([]{ unsigned char c; // the value is indeterminate until C++26, erroneous since C++26 +c; return true; }()); ```
Corrected example:
However, [expr.const] p5.8 and [expr.const] p5.11 are insufficient to reject this, because reading an erroneous
unsigned char
value is not erroneous behavior, and [expr.const] p5.11 only talks about indeterminate values.Or alternatively, if it's fine to propagate erroneous byte values until EB happens in constant evaluation, it would be more consistent to allow propagation of indeterminate byte values (until UB happens), given [expr.const] p14.2 has already forbidden an indeterminate or erroneous value in the final result of constant evaluation. This approach seems undesired per P1331R2, but I wonder whether it can simplify implementation of constant evaluator.
Suggested resolution:
Change [expr.const] p5.11 as indicated: