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

2026-05-10


3189. Implicitly deleted destructors for union-like classes

Section: 11.4.7  [class.dtor]     Status: open     Submitter: Jakub Jelinek     Date: 2026-05-04

Consider:

  union U1 {
    int a = 42;
    long b;
  } u1;

  union U2 {
    U2(int i): i(i) { }
    int i;
  } u2(5);

Both declarations ought to be well-formed, but the current rules (as amended by paper P3726R2) make both ill-formed.

Suggested resolution:

  1. Change in 11.4.4 [special] paragraph 7 as follows:

    For a class, its direct non-static data members, excluding anonymous union members (but including variant members thereof), its non-virtual direct base classes, and, if the class is not abstract (11.7.4 [class.abstract]), its virtual base classes are called its potentially constructed subobjects.
  2. Change in 11.4.7 [class.dtor] paragraph 4 as follows:

    A defaulted destructor for a class X is defined as deleted if
    • X is has a non-union class and any non-variant potentially constructed subobject has S of class type M (or possibly multidimensional array thereof) where either
      • S is not a variant member and M has a destructor that is deleted or is inaccessible from the defaulted destructor, or
    • X is a union and
      • overload resolution to select a constructor to default-initialize an object of type X either fails or selects a constructor that is either deleted or not trivial, or
      • X has a variant member V of class type M (or possibly multi-dimensional array thereof) where
      • S is a variant member, M has a destructor that is deleted, inaccessible from the defaulted destructor, or non-trivial, and either
        • V S has a default member initializer or
        • X has a user-provided constructor,
        and M has a destructor that is non-trivial, or,
    • for a virtual destructor, lookup of the non-array deallocation function results in an ambiguity or in a function that is deleted or inaccessible from the defaulted destructor.
  3. Change in 11.9.3 [class.base.init] bullet 9.2 as follows:

    In a non-delegating constructor other than an implicitly-defined copy/move constructor (11.4.5.3 [class.copy.ctor]), if a given potentially constructed subobject is not designated by a mem-initializer-id (including the case where there is no mem-initializer-list because the constructor has no ctor-initializer), then
    • if the entity is a non-static data member that has a default member initializer (11.4 [class.mem]) and either
      • the constructor's class is a union (11.5 [class.union]), and no other variant member of that union is designated by a mem-initializer-id or
      • the constructor's class is not a union, and, if the entity is a member of an anonymous union, no other member of that union is designated by a mem-initializer-id,
      the entity is initialized from its default member initializer as specified in 9.5 [dcl.init];
    • otherwise, if the entity is an anonymous union or a variant member (11.5.2 [class.union.anon]), no initialization is performed;
    • otherwise, the entity is default-initialized (9.5 [dcl.init]).