https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104163
Bug ID: 104163 Summary: Misleading diagnostic for incompletely initialized constinit variable Product: gcc Version: 12.0 Status: UNCONFIRMED Keywords: diagnostic Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: redi at gcc dot gnu.org Target Milestone: --- struct B { int i = 0; }; struct C { void* p; B b; constexpr C() = default; }; constinit C c{}; This is invalid because C::p is left uninitialized by the constructor, but GCC's warning is confusing: mut.C:13:13: error: 'constinit' variable 'c' does not have a constant initializer 13 | constinit C c{}; | ^ mut.C:13:15: error: 'C{B{0}}' is not a constant expression 13 | constinit C c{}; | ^ mut.C:13:15: error: 'C()' is not a constant expression because it refers to an incompletely initialized variable The "'C{B{0}}' is not a constant expression" makes it look like the problem is related to initialization of B. There is no mention of the p member. I spent quite a bit of time trying to figure out what was wrong in a more complex, deeply nested example. Clang tells you exactly what's wrong: mut.C:13:13: error: variable does not have a constant initializer constinit C c{}; ^~~ mut.C:13:1: note: required by 'constinit' specifier here constinit C c{}; ^~~~~~~~~ mut.C:13:13: note: subobject of type 'void *' is not initialized constinit C c{}; ^ mut.C:8:9: note: subobject declared here void* p; ^ 1 error generated. The notes about the void* are clear and precise. EDG is less clear, but at least still identifies C::p as the problem: "mut.C", line 13: error: expression must have a constant value constinit C c{}; ^ "mut.C", line 13: note: access to uninitialized subobject (member "C::p") constinit C c{}; ^ 1 error detected in the compilation of "mut.C".