[conv.lval] Make note and generalize comment on UB CWG2899 by eisenwave · Pull Request #7051 · cplusplus/draft (original) (raw)

The last sentence ([conv.lval] p3.4) is redundant at best, and defective at worst:

Otherwise, the object indicated by the glvalue is read ([defns.access]), and the value contained in the object is the prvalue result. If the result is an erroneous value ([basic.indet]) and the bits in the value representation are not valid for the object's type, the behavior is undefined.

It is misleading to single out erroneous values because this happens with any value (or lack thereof) in general. Consider the following example:

char c = 2; bool b; std::memcpy(&b, &c, 1); bool u = b;

We could consider memcpy to implicitly begin the lifetime of a new bool object within the storage of b, and because b is transparently replaceable by such an object, this is almost valid. However, because no value of bool corresponds to a value representation of 0x02 (at least in the Itanium ABI), the behavior is undefined because the lvalue-to-rvalue conversion of b reads the value of b, but no such value exists.

The current wording only mentions erroneous values, and leads the reader to believe that only erroneous values can lead to value representations that don't correspond to any value, but this is not accurate.

To fix this, I've generalized the wording so that it doesn't single out erroneous values anymore, and made it into a note, since it's already UB based on the wording in [defns.access].

At worst, the current wording is defective because it talks about the "result" of the lvalue-to-rvalue conversion, but there cannot possibly be a result if the access is UB already.