Here's the code. GCC with `-Wall -O3` warns that `x` is used uninitialized, even though it's zeroed. struct A { A() {} int x; }; struct B : A {}; int main() { B b = B(); return b.x; } Since `B` doesn't have a user-provided default constructor, value-initializing it like this performs zero-initialization, which propagates recursively (http://eel.is/c++draft/dcl.dcl#dcl.init.general-6.2) over all members, zeroing everything. Yet GCC incorrectly warns about `x` being uninitialized.
Did you miss that the implicit B constructor will just call A's constructor ?
Before calling A's constructor, it will zero `x` anyway. I was also surprised when I learned this yesterday, but it's what the standard says. 1. `()` performs value-initialization on B: http://eel.is/c++draft/dcl.dcl#dcl.init.general-16.4 2. Since B's ctor is not user-provided, that resolves to zero-initialization followed by default-initialization: http://eel.is/c++draft/dcl.dcl#dcl.init.general-9.1.2 3. Zero-initialization of B propagates to A, then propagates to `x` and zeroes it, regardless of A having a user-provided constructor or not: http://eel.is/c++draft/dcl.dcl#dcl.init.general-6.2 4. Lastly default-initialization of B calls B's constructor and in turn calls A's constructor.
We have int main () { int D.2848; { struct B b; try { b.D.2778.x = 0; B::B (&b); D.2848 = b.D.2778.x; return D.2848; but: void B::B (struct B * const this) { _1 = &this->D.2778; A::A (_1); } void A::A (struct A * const this) { *this = {CLOBBER}; so A::A invoked by B::B invalidates the initialized storage. Maybe a "different" B::B should have been called (one not invoking A::A?).
-fno-lifetime-dse fixes the issue (and the diagnostic)
Dup of bug 108993. *** This bug has been marked as a duplicate of bug 108993 ***