This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 110b. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2023-01-15


653. Copy assignment of unions

Section: 11.4.6  [class.copy.assign]     Status: CD2     Submitter: Jens Maurer     Date: 3 October 2007

[Voted into WP at July, 2009 meeting.]

How does copy assignment for unions work? For example,

  union U {
    int a;
    float b;
  };

  void f() {
    union U u = { 5 };
    union U v;
    v = u;    // what happens here?
  }

11.5 [class.union] is silent on the issue, therefore it seems that 11.4.5.3 [class.copy.ctor] applies. There is no special case for unions, thus paragraph 13 (memberwise assignment of subobjects) seems to apply. That would seem to imply these actions in the compiler-generated copy assignment operator:

  v.a = u.a;
  v.b = u.b;

And this is just wrong. For example, the lifetime of v.a ends once the second assignment reuses the memory of v.a.

We should probably prescribe “memcpy” copying for unions (both for the copy constructor and the assignment operator) unless the user provided his own special member function.

Proposed resolution (March, 2008):

  1. Change 11.4.5.3 [class.copy.ctor] paragraph 8 as follows:

  2. The implicitly-defined or explicitly-defaulted copy constructor for a non-union class X performs a memberwise copy of its subobjects...
  3. Add a new paragraph after 11.4.5.3 [class.copy.ctor] paragraph 8:

  4. The implicitly-defined or explicitly-defaulted copy constructor for a union X where all members have a trivial copy constructor copies the object representation (6.8 [basic.types]) of X. [Note: The behavior is undefined if X is not a trivial type. —end note]
  5. Change 11.4.5.3 [class.copy.ctor] paragraph 13 as follows:

  6. The implicitly-defined or explicitly-defaulted copy assignment operator for a non-union class X performs memberwise assignment of its subobjects...
  7. Add a new paragraph after 11.4.5.3 [class.copy.ctor] paragraph 13:

  8. The implicitly-defined or explicitly-defaulted copy assignment operator for a union X where all members have a trivial copy assignment operator copies the object representation (6.8 [basic.types]) of X. [Note: The behavior is undefined if X is not a trivial type. —end note]

Notes from the September, 2008 meeting:

The proposed wording needs to be updated to reflect the changes adopted in papers N2757 and N2762, resolving issue 683, which require “no non-trivial” special member functions instead of “a trivial” function. Also, the notes regarding undefined behavior are incorrect, because the member functions involved are defined as deleted when there are non-trivial members.

Proposed resolution (October, 2008):

  1. Change 11.4.5.3 [class.copy.ctor] paragraph 8 as follows:

  2. The implicitly-defined or explicitly-defaulted copy constructor for a non-union class X performs a memberwise copy of its subobjects...
  3. Add a new paragraph following 11.4.5.3 [class.copy.ctor] paragraph 8:

  4. The implicitly-defined or explicitly-defaulted copy constructor for a union X copies the object representation (6.8 [basic.types]) of X.
  5. Change 11.4.5.3 [class.copy.ctor] paragraph 13 as follows:

  6. The implicitly-defined or explicitly-defaulted copy assignment operator for a non-union class X performs memberwise assignment of its subobjects...
  7. Add a new paragraph following 11.4.5.3 [class.copy.ctor] paragraph 13:

  8. The implicitly-defined or explicitly-defaulted copy assignment operator for a union X copies the object representation (6.8 [basic.types]) of X.