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

2025-03-08


2999. Trivial unions changing existing behavior

Section: 11.4.5.2  [class.default.ctor]     Status: open     Submitter: Richard Smith     Date: 2025-02-14

Consider:

  union U { int a, b; };
  template<U u> class X {};
  constexpr U make() { U u; return u; }
  void f(X<make()>) {}

Before P3074R7, the template argument of X was a union object with no active member. Now, the default construction of U starts the lifetime of U::a because it has implicit-lifetime type (11.4.5.2 [class.default.ctor] paragraph 4).

This changes the mangling of f, because a union with no active member is different from a union with the first member active. More importantly, it is now ill-formed, because U::a is in-lifetime, but uninitialized (7.7 [expr.const] bullet 22.2).

Also consider the following implementation divergence

  struct E { };
  union U { E e; };
  template<U u> class X {};

  constexpr U make() { U u; return u; }
  constexpr U make2() { U u{}; return u; }

  void f(X<make()>) {}
  void f(X<make2()>) {}    // OK with clang; redefinition error with gcc

If any of those behavior changes are intended, an Annex C entry is needed.