Trivial copying of unions in core constant expressions
7.7 [expr.const]
Hubert Tong

Created on 2022-12-04.00:00:00 last changed 3 weeks ago


Date: 2023-01-07.14:34:08

Proposed resolution:

Add a new paragraph after 7.7 [expr.const] paragraph 6 as follows:

... to an object whose lifetime began within the evaluation of E.

For the purposes of determining whether E is a core constant expression, lvalue-to-rvalue conversion of an object of indeterminate value during the evaluation of a call to a trivial copy/move constructor or copy/move assignment operator of a union does not disqualify E from being a core constant expression unless the active member of the source union object contains a subobject of indeterminate value.

Date: 2022-12-04.00:00:00


  struct A { char c; int x; };
  union U { A a; };
  constexpr int f() {
    U u;
    u.a.c = 1;
    u.a.x = 2;
    U v = u; // indeterminate padding bytes read!
    return u.a.x;
  extern constexpr int x = f();

Subclause 7.7 [expr.const] bullet 5.11 added by P1331R2 prohibits lvalue-to-rvalue conversion of objects having indeterminate value during evaluation of a core constant expression. Trivial copy constructors of unions copy the object representation (not just the active member). The new prohibition causes cases where bytes not involved in the value presentation of the active member and having indeterminate values would prevent a union from being copied by a trivial copy constructor (for example, the padding bytes in the above case).

Note: The source of a union copy is never a prvalue within the evaluation of a trivial copy constructor because the reference parameter is bound to a glvalue.

Date User Action Args
2023-01-07 14:34:08adminsetstatus: open -> review
2022-12-04 12:32:54adminsetmessages: + msg7080
2022-12-04 00:00:00admincreate