c++ - Why can't I initialize non-const static member or static array in class? -
why can't initialize non-const static
member or static
array in class?
class { static const int = 3; static int b = 3; static const int c[2] = { 1, 2 }; static int d[2] = { 1, 2 }; }; int main() { 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: brace-enclosed initializer 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: brace-enclosed initializer 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 2 questions:
- why can't initialize
static
data members in class? - why can't initialize
static
arrays in class,const
array?
why can't initialize static
data members in class?
the c++ standard allows static constant integral or enumeration types initialized inside class. reason a
allowed initialized while others not.
reference:
c++03 9.4.2 static data members
§4
if static data member of const integral or const enumeration type, declaration in class definition can specify constant-initializer shall integral constant expression (5.19). in case, member can appear in integral constant expressions. member shall still defined in namespace scope if used in program , namespace scope definition shall not contain initializer.
what integral types?
c++03 3.9.1 fundamental types
§7
types bool, char, wchar_t, , signed , unsigned integer types collectively called integral types.43) synonym integral type integer type.
footnote:
43) therefore, enumerations (7.2) not integral; however, enumerations can promoted int, unsigned int, long, or unsigned long, specified in 4.5.
workaround:
you use enum trick initialize array inside class definition.
class { static const int = 3; enum { arrsize = 2 }; static const int c[arrsize] = { 1, 2 }; };
why standard not allow this?
bjarne explains aptly here:
a class typically declared in header file , header file typically included many translation units. however, avoid complicated linker rules, c++ requires every object has unique definition. rule broken if c++ allowed in-class definition of entities needed stored in memory objects.
why static const
integral types & enums allowed in-class initialization?
the answer hidden in bjarne's quote read closely,
"c++ requires every object has unique definition. rule broken if c++ allowed in-class definition of entities needed stored in memory objects."
note static const
integers can treated compile time constants. compiler knows integer value not change anytime , hence can apply own magic , apply optimizations, compiler inlines such class members i.e, not stored in memory anymore, need of being stored in memory removed, gives such variables exception rule mentioned bjarne.
it noteworthy note here if static const
integral values can have in-class initialization, taking address of such variables not allowed. 1 can take address of static member if (and if) has out-of-class definition.this further validates reasoning above.
enums allowed because values of enumerated type can used ints expected.see citation above
how change in c++11?
c++11 relaxes restriction extent.
c++11 9.4.2 static data members
§3
if static data member of const literal type, declaration in class definition can specify brace-or-equal-initializer in every initializer-clause assignment-expression constant expression. static data member of literal type can declared in class definition
constexpr specifier;
if so, declaration shall specify brace-or-equal-initializer in every initializer-clause assignment-expression constant expression. [ note: in both these cases, member may appear in constant expressions. —end note ] member shall still defined in namespace scope if used in program , namespace scope definition shall not contain initializer.
also, c++11 will allow(§12.6.2.8) non-static data member initialized declared(in class). mean easy user semantics.
note these features have not yet been implemented in latest gcc 4.7, might still compilation errors.
Comments
Post a Comment