Title
Trivial copying of unions in core constant expressions
Status
c++23
Section
7.7 [expr.const]
Submitter
Hubert Tong

Created on 2022-12-04.00:00:00 last changed 16 months ago

Messages

Date: 2023-02-07.17:18:40

Proposed resolution (approved by CWG 2023-02-07):

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, the evaluation of a call to a trivial copy/move constructor or copy/move assignment operator of a union is considered to copy/move the active member of the union, if any. [ Note: The copy/move of the active member is trivial. -- end note ]

Date: 2023-01-15.00:00:00

Proposed resolution (January, 2023):

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: 2023-02-15.00:00:00

[Accepted as a DR at the February, 2023 meeting.]

Consider:

  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.

History
Date User Action Args
2023-07-16 13:00:43adminsetstatus: open -> c++23
2023-07-16 13:00:43adminsetstatus: dr -> open
2023-02-18 18:43:04adminsetstatus: ready -> dr
2023-02-10 23:01:52adminsetstatus: tentatively ready -> ready
2023-02-07 17:18:40adminsetstatus: review -> tentatively ready
2023-02-07 14:43:26adminsetmessages: + msg7168
2023-01-07 14:34:08adminsetstatus: open -> review
2022-12-04 12:32:54adminsetmessages: + msg7080
2022-12-04 00:00:00admincreate