I have a class A which has two static variables. I'd like to initialize one with another, unrelated static variable, just like this:
#include <iostream>
class A
{
public:
static int a;
static int b;
};
int A::a = 200;
int a = 100;
int A::b = a;
int main(int argc, char* argv[])
{
std::cout << A::b << std::endl;
return 0;
}
The output is 200. So, could anyone tell me why?
C++ guarantees that variables in a compilation unit (. cpp file) are initialised in order of declaration. For number of compilation units this rule works for each one separately (I mean static variables outside of classes). But, the order of initialization of variables, is undefined across different compilation units.
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.
In the initializer list, the order of execution takes place according to the order of declaration of member variables. While using the initializer list for a class in C++, the order of declaration of member variables affects the output of the program. Program 1: C++
For the static variables, we have to initialize them after defining the class. To initialize we have to use the class name then scope resolution operator (::), then the variable name. Now we can assign some value. The following code will illustrate the of static member initializing technique.
That's correct according to the lookup rules. [basic.lookup.unqual]/13 says:
A name used in the definition of a static data member of class X (after the qualified-id of the static member) is looked up as if the name was used in a member function of X. [ Note: [class.static.data] further describes the restrictions on the use of names in the definition of a static data member. — end note ]
Since the unqualified a
is looked up as if you are inside a member function, it must find the member A::a
first. The initialization order of A::a
and A::b
doesn't affect the lookup, though it affects how well defined the result is.
So, could anyone tell me why?
This is clearly stated in basic.scope.class/4, emphasis mine:
The potential scope of a declaration that extends to or past the end of a class definition also extends to the regions defined by its member definitions, even if the members are defined lexically outside the class (this includes static data member definitions, nested class definitions, and member function definitions, including the member function body and any portion of the declarator part of such definitions which follows the declarator-id, including a parameter-declaration-clause and any default arguments).
Thus, when you have
int A::a = 200;
int a = 100;
int A::b = a; // note the '::' scope resolution operator
// OUTPUT: 200
a
actually refers to A::a
because the class scope is extended by A::b
.
Unlike if you have:
int A::a = 200;
int a = 100;
int b = a; // note b is not A::b
// i.e. without the '::', scope resolution operator
// OUTPUT: 100
a
would refer to the (global) ::a
since b
here is not a member of class A
,
i.e. no class scope extension.
c++draft/class.static
If an unqualified-id is used in the definition of a static member following the member's declarator-id, and name lookup ([basic.lookup.unqual]) finds that the unqualified-id refers to a static member, enumerator, or nested type of the member's class (or of a base class of the member's class), the unqualified-id is transformed into a qualified-id expression in which the nested-name-specifier names the class scope from which the member is referenced. [ Note: See [expr.prim.id] for restrictions on the use of non-static data members and non-static member functions. — end note ]
It says the unqualified-id is transformed into a qualified-id expression in your situation.
int A::b = a;
You can set qualified-id but has no nested-name-specifier like this.
int A::b = ::a;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With