Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ static member variable and its initialization


For static member variables in C++ class - the initialization is done outside the class. I wonder why? Any logical reasoning/constraint for this? Or is it purely legacy implementation - which the standard does not want to correct?

I think having initialization in the class is more "intuitive" and less confusing.It also gives the sense of both static and global-ness of the variable. For example if you see the static const member.

like image 751
kumar_m_kiran Avatar asked Dec 28 '10 16:12

kumar_m_kiran


People also ask

How are static variables initialized in C?

In C, static variables can only be initialized using constant literals. For example, following program fails in compilation. If we change the program to following, then it works without any error.

How do you initialize a static member?

The initializer for a static data member is in the scope of the class declaring the member. A static data member can be of any type except for void or void qualified with const or volatile . You cannot declare a static data member as mutable . You can only have one definition of a static member in a program.

How are static variables initialized?

Static variables are initialized only once , at the start of the execution. These variables will be initialized first, before the initialization of any instance variables. A single copy to be shared by all instances of the class. A static variable can be accessed directly by the class name and doesn't need any object.

What is a static member variable?

A variable declared static within a module (but outside the body of a function) is accessible by all functions within that module. However, it is not accessible by functions from other modules. static members exist as members of the class rather than as an instance in each object of the class.


2 Answers

Fundamentally this is because static members must be defined in exactly one translation unit, in order to not violate the One-Definition Rule. If the language were to allow something like:

struct Gizmo {   static string name = "Foo"; }; 

then name would be defined in each translation unit that #includes this header file.

C++ does allow you to define integral static members within the declaration, but you still have to include a definition within a single translation unit, but this is just a shortcut, or syntactic sugar. So, this is allowed:

struct Gizmo {   static const int count = 42; }; 

So long as a) the expression is const integral or enumeration type, b) the expression can be evaluated at compile-time, and c) there is still a definition somewhere that doesn't violate the one definition rule:

file: gizmo.cpp

#include "gizmo.h"  const int Gizmo::count; 
like image 166
John Dibling Avatar answered Oct 16 '22 03:10

John Dibling


In C++ since the beginning of times the presence of an initializer was an exclusive attribute of object definition, i.e. a declaration with an initializer is always a definition (almost always).

As you must know, each external object used in C++ program has to be defined once and only once in only one translation unit. Allowing in-class initializers for static objects would immediately go against this convention: the initializers would go into header files (where class definitions usually reside) and thus generate multiple definitions of the same static object (one for each translation unit that includes the header file). This is, of course, unacceptable. For this reason, the declaration approach for static class members is left perfectly "traditional": you only declare it in the header file (i.e. no initializer allowed), and then you define it in a translation unit of your choice (possibly with an initializer).

One exception from this rule was made for const static class members of integral or enum types, because such entries can for Integral Constant Expressions (ICEs). The main idea of ICEs is that they are evaluated at compile time and thus do no depend on definitions of the objects involved. Which is why this exception was possible for integral or enum types. But for other types it would just contradict the basic declaration/definition principles of C++.

like image 26
AnT Avatar answered Oct 16 '22 03:10

AnT