21

In C and C++ all static variables are initialized by default to ZERO.

This is not the case of static class data members. Why is that?

#include <iostream>
using namespace std;

int var;

class MyClass
{
public:
    static int classVar;
};
int MyClass::classVar = 0;  // Why I have to init it here?

int main(void)
{
    cout << ::var << endl;          // this is initalized to ZERO by default
    static int var;
    cout << var << endl;            // and this also is initalized to Zero
    cout << MyClass::classVar << endl;

    return 0;
}
Mat
  • 202,337
  • 40
  • 393
  • 406
Muhammad Hewedy
  • 29,102
  • 44
  • 127
  • 219
  • You are not sure **var** is initialized to 0. It's possible, sometimes probable, but not sure. – Alessandro Pezzato Nov 25 '11 at 10:45
  • 3
    @AlessandroPezzato: Actually, the Standard is explicit about zeroing out memory for the all global variables before executing dynamic initialization... apart from those built-ins to which a literal value is affected, those I think can be affected directly (under the as-if rule) since it's unobservable. – Matthieu M. Nov 25 '11 at 10:54

3 Answers3

30

At class scope,

int MyClass::classVar = 0;  // Why I have to init it here?

is a definition and

static int classVar;

is a declaration, ie. a promise the variable will be defined somewhere: you must define exactly once the variables you declare.

The rationale is that the class declaration will likely be included in multiple source files. Would a part of it be a definition, it would take place multiply: this is erroneous (exceptions are inline [member] functions).

Note that according to value initialization rules, you can get along with

int MyClass::classVar;  // Zero-initialized !

as a definition.

Variables declared at namespace scope are definitions too (unless they are extern qualified):

int var;

is a declaration, and a definition: if you put this into a header and include it in multiple translation units, you have an error ("multiply defined symbol", or something along those lines).

[Note that in C++ (and not in C), if the var above is const, it becomes automatically static and there is no violation of the One Definition Rule should it be put into a multiply included header. This goes slightly off topic, but feel free to ask details]

Alexandre C.
  • 55,948
  • 11
  • 128
  • 197
  • 3
    I'm not sure that is what is being asked. I read that as "why do I have to put `= 0;` there?" – Mat Nov 25 '11 at 10:45
  • @Alexandre C.: It would be good if you also explain why that is needed. – Nawaz Nov 25 '11 at 10:49
  • 3
    So, `int MyClass::classVar;` should already suffice if you just require Zero-initialization? Never tried that but according to the Std and a deleted answer, it actually does. – zerm Nov 25 '11 at 11:10
  • 1
    "=0" is not mandatory. Even without this also it will initialize to zero only. – rakesh Nov 25 '11 at 11:59
  • In case of **"int var** you said ** if you put this into a header and include it in multiple translation units, you have an error ("multiply defined symbol", or something along those lines).** but doesn't #ifndef ... #define ... #endif guard avoid this problem (not saying you are wrong just wanted to make sure) – pokche Oct 31 '16 at 18:20
  • In summary, "Why I have to init it here?" -- No, u don't have to, u even shouldn't do so. [In common](https://stackoverflow.com/a/185848/1819810), declarations goes to header file `*.h`, while definition (or initialization) goes to source file `*.cpp`. – Weekend Mar 07 '19 at 07:22
7

C++ FAQ 10.12 states that:

static data members must be explicitly defined in exactly one compilation unit.

From C++ FAQ http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12

Does that answer your question or were you after a reference to the C++ standard itself?

Talvalin
  • 7,789
  • 2
  • 30
  • 40
2

You have to initialize your static class data variables, because you have to tell the compiler what their value is. Classes need not have a notion of a default value.

Variables types have a logical "zero value", for int it is 0, for double 0.0, for a string "" etc. In contrast, classes do not necessarily have a default value. Consider, for example class Rectangle. What is its zero value - a rectangle with zero square or a rectangle with unit side length? For static variables, a compiler asks you to define yourself, what value your static variable must have, because not every data type can be initialized by a default value.

Pavlo Dyban
  • 1,297
  • 2
  • 15
  • 28
  • 2
    I think you are mistaken here: nothing prevents you from defining a static variable and not initializing it. If the variable is an instance of a class, then its constructor will be called. – qdii Nov 25 '11 at 11:18
  • The static variable have to be defined. Constructor will not initialize it. Consider below example... If "int test::k;" will be commented it will not compile. class test { public: static int k; }; int test::k; int main() { test t; cout<< t.k; return 0; } – rakesh Nov 25 '11 at 12:02
  • @victor Yes, you are right, thank you for noting that out to me. The question was about defining a static variable, and not its initialization. – Pavlo Dyban Nov 25 '11 at 13:27