Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why static variable needs to be explicitly defined?

Tags:

c++

static

In the class:

class foo { public:     static int bar; //declaration of static data member };  int foo::bar = 0; //definition of data member 

We have to explicitly define the static variable, otherwise it will result in a

undefined reference to 'foo::bar'

My question is:

Why do we have to give an explicit definition of a static variable?


Please note that this is NOT a duplicate of previously asked undefined reference to static variable questions. This question intends to ask the reason behind explicit definition of a static variable.

like image 365
shauryachats Avatar asked Mar 24 '15 02:03

shauryachats


People also ask

Where static variable should be defined?

Static variables can be defined inside or outside the function. They are local to the block. The default value of static variables is zero. The static variables are alive till the execution of the program.

Why do we need to initialize static variables?

You initialize a static object with a constant expression, or an expression that reduces to the address of a previously declared extern or static object, possibly modified by a constant expression.

Why static member variable defined outside class?

Because static member variables are not part of the individual class objects (they are treated similarly to global variables, and get initialized when the program starts), you must explicitly define the static member outside of the class, in the global scope.

Why use static variable to hold context is not a good idea?

Static variables are generally considered bad because they represent global state and are therefore much more difficult to reason about. In particular, they break the assumptions of object-oriented programming.


2 Answers

From the beginning of time C++ language, just like C, was built on the principle of independent translation. Each translation unit is compiled by the compiler proper independently, without any knowledge of other translation units. The whole program only comes together later, at linking stage. Linking stage is the earliest stage at which the entire program is seen by linker (it is seen as collection of object files prepared by the compiler proper).

In order to support this principle of independent translation, each entity with external linkage has to be defined in one translation unit, and in only one translation unit. The user is responsible for distributing such entities between different translation units. It is considered a part of user intent, i.e. the user is supposed to decide which translation unit (and object file) will contain each definition.

The same applies to static members of the class. Static members of the class are entities with external linkage. The compiler expects you to define that entity in some translation unit. The whole purpose of this feature is to give you the opportunity to choose that translation unit. The compiler cannot choose it for you. It is, again, a part of your intent, something you have to tell the compiler.

This is no longer as critical as it used to be a while ago, since the language is now designed to deal with (and eliminate) large amount of identical definitions (templates, inline functions, etc.), but the One Definition Rule is still rooted in the principle of independent translation.

In addition to the above, in C++ language the point at which you define your variable will determine the order of its initialization with regard to other variables defined in the same translation unit. This is also a part of user intent, i.e. something the compiler cannot decide without your help.


Starting from C++17 you can declare your static members as inline. This eliminates the need for a separate definition. By declaring them in that fashion you effectively tell compiler that you don't care where this member is physically defined and, consequently, don't care about its initialization order.

like image 156
AnT Avatar answered Sep 24 '22 13:09

AnT


In early C++ it was allowed to define the static data members inside the class which certainly violate the idea that class is only a blueprint and does not set memory aside. This has been dropped now.

Putting the definition of static member outside the class emphasize that memory is allocated only once for static data member (at compile time). Each object of that class doesn't have it own copy.

like image 41
haccks Avatar answered Sep 23 '22 13:09

haccks