https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118285
--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> --- With minor tweaks to that: --- pr118285-3.C 2025-01-28 16:30:15.798692471 +0100 +++ pr118285-5.C 2025-01-28 16:46:09.572904490 +0100 @@ -6,21 +6,21 @@ template <typename T> struct initializer } struct A { char *a; - union { char b[8]; long c; }; - constexpr A (const char *x) : a(b) + union U { char b[8]; long c; } u; + constexpr A (const char *x) : a(u.b) { for (int i = 0; i < 8; ++i) - b[i] = 0; + u.b[i] = i; } constexpr ~A () { if (!foo ()) - bar (c); + bar (u.c); } constexpr bool foo () { char *x = a; - if (x == b) + if (x == u.b) return true; return false; } so that it avoids using anonymous union just in case and initializes to nonzero the b stuff, if I cxx_eval_constant_expression the whole *this in A::~A(), I get {.a=(char *) &D.2743.u.b, .u={.b={0, 1, 2, 3, 4, 5, 6, 7}}} when evaluated as rvalue and D.2730[0] when evaluated as lvalue. So this is about mismatch with what value the a member has been initialized, so no wonder that foo () returns false.