Why can't I initialize non-const static
member or static
array in a class?
class A
{
static const int a = 3;
static int b = 3;
static const int c[2] = { 1, 2 };
static int d[2] = { 1, 2 };
};
int main()
{
A a;
return 0;
}
the compiler issues following errors:
g++ main.cpp
main.cpp:4:17: error: ISO C++ forbids in-class initialization of non-const static member ‘b’
main.cpp:5:26: error: a brace-enclosed initializer is not allowed here before ‘{’ token
main.cpp:5:33: error: invalid in-class initialization of static data member of non-integral type ‘const int [2]’
main.cpp:6:20: error: a brace-enclosed initializer is not allowed here before ‘{’ token
main.cpp:6:27: error: invalid in-class initialization of static data member of non-integral type ‘int [2]’
I have two questions:
- Why can't I initialize
static
data members in class? - Why can't I initialize
static
arrays in class, even theconst
array?
Best Answer
Why I can't initialize
static
data members in class?The C++ standard allows only static constant integral or enumeration types to be initialized inside the class. This is the reason
a
is allowed to be initialized while others are not.Reference:
C++03 9.4.2 Static data members
§4
What are integral types?
C++03 3.9.1 Fundamental types
§7
Footnote:
Workaround:
You could use the enum trick to initialize an array inside your class definition.
Why does the Standard does not allow this?
Bjarne explains this aptly here:
Why are only
static const
integral types & enums allowed In-class Initialization?The answer is hidden in Bjarne's quote read it closely,
"C++ requires that every object has a unique definition. That rule would be broken if C++ allowed in-class definition of entities that needed to be stored in memory as objects."
Note that only
static const
integers can be treated as compile time constants. The compiler knows that the integer value will not change anytime and hence it can apply its own magic and apply optimizations, the compiler simply inlines such class members i.e, they are not stored in memory anymore, As the need of being stored in memory is removed, it gives such variables the exception to rule mentioned by Bjarne.It is noteworthy to note here that even if
static const
integral values can have In-Class Initialization, taking address of such variables is not allowed. One can take the address of a static member if (and only if) it has an out-of-class definition.This further validates the reasoning above.enums are allowed this because values of an enumerated type can be used where ints are expected.see citation above
How does this change in C++11?
C++11 relaxes the restriction to certain extent.
C++11 9.4.2 Static data members
§3
Also, C++11 will allow(§12.6.2.8) a non-static data member to be initialized where it is declared(in its class). This will mean much easy user semantics.
Note that these features have not yet been implemented in latest gcc 4.7, So you might still get compilation errors.