struct sa
{
struct sb { int a = 123;};
inline static sb b;
};
The above code generates an error:
main.cpp:25:20: error: default member initializer for ‘sa::sb::a’ required before the end of its enclosing class
inline static sb b;
^
main.cpp:24:21: note: defined here
struct sb { int a = 123;};
^~~~~~
Removing the inline
keyword or the default member initializer works. But just from the output, I don't understand why this usage is wrong.
Static local variables are not allowed to be defined within the body of an inline function. C++ functions implemented inside of a class declaration are automatically defined inline.
A variable declared inline has the same semantics as a function declared inline: it can be defined, identically, in multiple translation units, must be defined in every translation unit in which it is used, and the behavior of the program is as if there was exactly one variable.
In C++ (before C++17 version), we cannot initialize the value of static variables directly in the class. We have to define them outside of the class.
Static variables are initialized to 0. It is initialized only once. Throughout the program, only one copy of the static member variable is created for the entire class hence static member variables are also called class variables. It is shared by all instances of the class.
I think this code is correct and should be accepted; gcc and clang are erring on the side of caution in order to avoid the defect of Core Issue 1397.
That issue ruled that a program is ill-formed if a NSDMI (non-static data member initializer) causes the class's defaulted default constructor to be generated.
However your code doesn't do that. The NSDMI is just an integer literal. The example that prompted this issue had code like int a = ( (sa(), 123) );
What I guess might be happening is: The standard also says that , when processing the NSDMI, the class sa
should be treated as complete. So perhaps the compilers are deferring the NSDMI processing until after the closing brace of sa
is reached; and then flagging the error because inline static sb b;
would generate sb::sb()
.
Possibly the standard is still defective and nobody thought of your example until now.
As a workaround you can explicitly provide the troublesome constructor:
struct sb { int a = 123; sb() {} };
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With