https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93969
Bug ID: 93969 Summary: Static data member cannot be initialized in place, if it is of a nested class type with a default argument in its constructor. Product: gcc Version: 9.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: igusarov at mail dot ru Target Milestone: --- Dear gcc developers, x86_64-gcc-9.2 available online at godbolt.org, refuses to compile a sample program which I believe is well-formed: struct Outer { struct Inner { Inner(int arg = 23); }; static inline Inner x{}; // (1) }; If invoked with a sole "-std=c++17" command-line option, the compilation fails at line marked (1) and the following error is reported: error: call to 'Outer::Inner::Inner(int)' uses the default argument for parameter 1, which is not yet defined The sample program looks well-formed to me because of the following reasoning: (clause numbers are per N4659 C++17 draft at http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf ) 1) Class Outer::Inner is fully defined at its closing brace (12.2/p6) and therefore is already a complete-type before Outer::x data member is declared; 2) The declaration of static inline data member Outer::x comes with a brace-initializer (12.2/p8) which means that it is also the definition (12.2.3.2/p3), also initializing-declaration and defining declaration (11.6/p21); 3) Outer::x is direct-list-initialized (11.6/p16, 11.6/p17); the initializer list is empty; 4) Class Outer::Inner has a user-defined constructor Outer::Inner::Inner(int). That constructor is the default constructor because every formal parameter has a corresponding default argument (15.1/p4); 5) Combination of points 3) and 4) means that Outer::x should be default-initialized (11.6.4/p3.4, 11.6/p8.1); 6) Default initialization of Outer::x should be performed by calling its matching constructor with an empty argument list (11.6/p7.1); 7) Each time the constructor is called with no arguments, default argument should be evaluated for the corresponding parameter (11.3.6/p9); 8) Default argument to that constructor is an integral constant expression which is already defined. So it seems that evaluation of the said default argument should cause no problem. ---- P.S. clang-9.0.0 also reports a similar error.