This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115b. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-08-20
(From editorial issue #7051.)
Consider:
static_assert(sizeof(bool) == 1); // assumption for the example bool f() { char c = 2; bool b = true; memcpy(&b, &c, 1); // #1 return b; // #2 }
Assuming that false and true are represented as 0 and 1, the value representation of b now has a bad value. This should, but does not, result in undefined behavior during the lvalue-to-rvalue conversion at #2.
Proposed resolution (approved by CWG 2024-08-16):
Change in 7.3.2 [conv.lval] paragraph 3 as follows:
The result of the conversion is determined according to the following rules:
- If T is cv std::nullptr_t, the result is a null pointer constant (7.3.12 [conv.ptr]). [Note 1: Since the conversion does not access the object to which the glvalue refers, there is no side effect even if T is volatile-qualified (6.9.1 [intro.execution]), and the glvalue can refer to an inactive member of a union (11.5 [class.union]). —end note]
- Otherwise, if T has a class type, the conversion copy-initializes the result object from the glvalue.
- Otherwise, if the object to which the glvalue refers contains an invalid pointer value (6.7.5.5.3 [basic.stc.dynamic.deallocation]), the behavior is implementation-defined.
- Otherwise, if the bits in the value representation of the object to which the glvalue refers are not valid for the object's type, the behavior is undefined. [ Example:
bool f() { bool b = true; char c = 42; memcpy(&b, &c, 1); return b; // undefined behavior if 42 is not a valid value representation for bool }
-- end example ]- Otherwise, the object indicated by the glvalue is read (3.1 [defns.access]), and the value contained in the object is the prvalue result.
If the result is an erroneous value (6.7.4 [basic.indet]) and the bits in the value representation are not valid for the object's type, the behavior is undefined.