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

2024-10-26


2464. Constexpr launder and unions

Section: 17.6.5  [ptr.launder]     Status: CD6     Submitter: Hubert Tong     Date: 2020-11-07

According to 17.6.5 [ptr.launder], referring to std::launder,

An invocation of this function may be used in a core constant expression whenever the value of its argument may be used in a core constant expression.

It is not clear whether this wording is intended to permit an example like

  #include <new>

  struct A { char x; };

  union U {
    A a;
    A a2;
  };

  constexpr A foo() {
    U u = {{42}};
    A *ap = &u.a2;
    return *std::launder(ap);
  }

  extern constexpr A globA = foo();

In particular, is the wording intended to restrict use of std::launder in a constant expression to cases in which the function returns its argument unchanged? As a further example, consider

  #include <new>

  struct A { char x; };
  struct B { A a; };
  struct BytesAndMore {
    unsigned char bytes[sizeof(A)];
    unsigned char more;
  };

  union U {
    BytesAndMore bytes;
    A a;
    B b;
  };

  constexpr B foo() {
    U u;
    A *ap = &u.a;
    B *bp = &u.b;
    u.bytes.more = 0;
    std::launder(ap)->x = 42;
    return *std::launder(bp);
  }

  extern constexpr B globB = foo();

Notes from the December, 2020 teleconference:

See also LWG issue 3495.