0

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?

2
  • Very important background information: What does odr-used mean?
    – Ben Voigt
    Commented Apr 26, 2018 at 1:52
  • Only const integral or enum members are allowed to be initialised this way Commented May 8, 2018 at 21:35

3 Answers 3

3

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.

2
  • 1
    The 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.M
    Commented 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
    – xvnm
    Commented May 9, 2018 at 8:44
1

One needs a bit of space in memory. Const do not - they can be hard coded.

17
  • 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 Heal
    Commented 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. Furthermore const objects can require dynamic initialization.
    – Ben Voigt
    Commented Apr 26, 2018 at 1:48
  • @BenVoigt - I have read his comment a few times - I cannot see the word "dynamic"
    – Ed Heal
    Commented 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.M
    Commented Apr 26, 2018 at 1:51
-1

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.

4
  • classes are usually defined in header file -.> Try declared in the header file
    – Ed Heal
    Commented Apr 26, 2018 at 2:10
  • Classes are usually defined in a header file.
    – Ben Voigt
    Commented Apr 26, 2018 at 2:52
  • @BenVoigt - Defined is what they do. Declared is what they are supposed to do. Hence being in the header file
    – Ed Heal
    Commented 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)
    – Ben Voigt
    Commented May 8, 2018 at 22:43

Not the answer you're looking for? Browse other questions tagged or ask your own question.