When I tried to initialize the static member variables at the time of declaration inside the class, compiler is throwing error as expected because we need to explicitly allocate the space for static member variables outside the class. I thought this should be same for static const variables. But to my surprise, initialization of static const member variables inside the class is working fine. Can any one please let me know why normal static member variable initialization is not allowed in the same way?
3 Answers
I assume that you meant
// inside class definition block
static const int a = 0;
static int b = 0; // error
C++ Standard 9.4.2/4,
If a static data member is of const integral or const enumeration type, its declaration in the class definition can specify a constant-initializer which shall be an integral constant expression (5.19). In that case, the member can appear in integral constant expressions. The member shall still be defined in a name- space scope if it is used in the program and the namespace scope definition shall not contain an initializer.
It is specified in standard.
Edit:
as M.M pointed out, above quotation is actually not what the Standard says, and the correct one is C++ Standard 12.2.3.2/3
If a non-volatile non-inline const static data member is of integral or enumeration type, its declaration in the class definition can specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression (8.20). The member shall still be defined in a namespace scope if it is odr-used (6.2) in the program and the namespace scope definition shall not contain an initializer. An inline static data member may be defined in the class definition and may specify a brace-or-equal-initializer . If the member is declared with the constexpr specifier, it may be redeclared in namespace scope with no initializer (this usage is deprecated; see D.1). Declarations of other static data members shall not specify a brace-or-equal-initializer.
-
1The text you quote does not appear in the current C++ Standard; and section 9.4.2 is about the
switch
statement. You should specify which document you are quoting. (and preferably quote the latest Standard)– M.MCommented May 8, 2018 at 21:46 -
@M.M Thx for the pointing out the problem. I thought the quotation was from the Standard because it was already used to answer another question. I've checked the document you provided and fixed my answer. thx– xvnmCommented May 9, 2018 at 8:44
One needs a bit of space in memory. Const do not - they can be hard coded.
-
It’s not just that they can be hard coded, they MUST be. But you’re right, the space required for const values is known at compile time, and is accounted for in the memory allocated for the program itself, whereas static vars can change during runtime so they must be allocated at runtime. Commented Apr 26, 2018 at 1:46
-
@BrianDriscoll - I concur - I was trying not to be too blunt– Ed HealCommented Apr 26, 2018 at 1:47
-
@Brian: What? Just because the value can change doesn't mean the allocation must be dynamic.
char a[4] = { f(), g(), h() }
is always exactly 4 bytes not matter how much work goes into determining its value. Furthermoreconst
objects can require dynamic initialization. Commented Apr 26, 2018 at 1:48 -
@BenVoigt - I have read his comment a few times - I cannot see the word "dynamic"– Ed HealCommented Apr 26, 2018 at 1:50
-
2@BrianDriscoll static const variables may still require a memory address if the
&
operator is used on them, for example, so your logic doesn't hold up. Also, in both cases the space required is known at compile time.– M.MCommented Apr 26, 2018 at 1:51
classes are usually declared in header files. Header files can be included multiple times in body files. If a static member, which needs memory, is defined within a class, than there will be a different copy of such a member in different body files. This will kill the idea of static members.
Constants on the other hand do not use memory and are compile-only constructs. therefore declaring them in the classes does not do any harm.
-
classes are usually defined in header file -.> Try declared in the header file– Ed HealCommented Apr 26, 2018 at 2:10
-
-
@BenVoigt - Defined is what they do. Declared is what they are supposed to do. Hence being in the header file– Ed HealCommented Apr 26, 2018 at 3:34
-
@EdHeal: Every definition is also a declaration. Typically a header file is the correct place to define a type. It may be preceded by forward declarations to resolve circular dependency problems, but the full type definition also belongs in a header file, with limited exceptions like
FILE
where it is intended for most users to treat it as an opaque type (and even then, it will be defined in a private header file and included into multiple source files operating on it). Lambdas are examples of types which often are defined only in implementation files (and they aren't declared in headers) Commented May 8, 2018 at 22:43
integral
orenum
members are allowed to be initialised this way