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;
}
2
  • You are not sure var is initialized to 0. It's possible, sometimes probable, but not sure. Commented Nov 25, 2011 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. Commented Nov 25, 2011 at 10:54

3 Answers 3

32

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]

Sign up to request clarification or add additional context in comments.

7 Comments

I'm not sure that is what is being asked. I read that as "why do I have to put = 0; there?"
@Alexandre C.: It would be good if you also explain why that is needed.
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.
"=0" is not mandatory. Even without this also it will initialize to zero only.
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)
|
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?

Comments

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.

3 Comments

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.
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; }
@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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.