scdmb
scdmb

Reputation: 15621

Order of evaluation of names declared in class

There is this code:

#include <iostream>

const int c = 3;

struct A {
   static int f() { return c; }
   static const int c = 2;
};

int main() {
   std::cout << A::f() << std::endl; // 2
   return 0;
}

How does it happen that variable c defined inside class A is used in function f instead of variable c defined in global scope although global variable c is declared first?

Upvotes: 0

Views: 77

Answers (3)

tglman
tglman

Reputation: 527

Is not a question of declaring order but of variable scope, the used variable are searched before in the current method/function after in the class/struct and a the and in the global context, example:

#include <iostream>

const int c = 3;

struct A {
   static void print() { 
      int c = 4
      std::cout <<"Method Scope:"<< c << std::endl; // 4
      std::cout <<"Class/Struct Scope:"<< A::c << std::endl; // 2 here you can use alse ::A::c
      std::cout <<"Global Scope:"<< ::c << std::endl; // 3
   }
   static const int c = 2;
};

struct B {
   static void print() { 
      std::cout <<"Method Scope:"<< c << std::endl; // 2
      std::cout <<"Class/Struct Scope:"<< B::c << std::endl; // 2 here you can use alse ::A::c
      std::cout <<"Global Scope:"<< ::c << std::endl; // 3
   }
   static const int c = 2;
};

struct C {
   static void print() { 
      std::cout <<"Method Scope:"<< c << std::endl; // 3
      //std::cout <<"Class/Struct Scope:"<< C::c << std::endl; //is inpossible ;)
      std::cout <<"Global Scope:"<< ::c << std::endl; // 3
   }
};

int main() {
   A::print();
   B::print();
   C::print();
   return 0;
}

Upvotes: 1

4pie0
4pie0

Reputation: 29724

imagine that you have long code which uses many variables, do you want them to be called instead these from a class to which function belongs? stating:

a or b

in class means

this->a

this->b

and if you want global variable to be visible you have to use it like

::a or ::b inside this function, so via:

static int f() { return ::c; }

From the standard docs, Sec 3.3.1

Every name is introduced in some portion of program text called a declarative region, which is the largest part of the program in which that name is valid, that is, in which that name may be used as an unqualified name to refer to the same entity. In general, each particular name is valid only within some possibly discontiguous portion of program text called its scope. To determine the scope of a declaration, it is sometimes convenient to refer to the potential scope of a declaration. The scope of a declaration is the same as its potential scope unless the potential scope contains another declaration of the same name. In that case, the potential scope of the declaration in the inner (contained) declarative region is excluded from the scope of the declaration in the outer (containing) declarative region.

this means that the potential scope is same as the scope of the declaration unless another (inner) declaration occurs. If occurred, the potential scope of the outer declaration is removed and just the inner declaration's holds, so your global variable is hidden.

Upvotes: 0

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726639

It does not matter which variable is declared first: if a class has a variable with the same name in it, that variable trumps the global variable. Otherwise you could get existing code in a lot of trouble simply by declaring a global variable with a name of one of its member variables!

Of course your class can use scope resolution operator to reference the global c directly:

static int f() { return ::c; }

Now your program will print 3 instead of 2.

Upvotes: 3

Related Questions