I am learning C++ using the books listed here. In particular, i read about overloading. So after reading i am trying out different examples to clear my concept further. One such example whose output i am unable to understand is given below:
int Name = 0;
class Name
{
int x[2];
};
void func()
{
std::cout << sizeof(Name) << std::endl; //My question is: Why here Name refers to the integer variable Name and not class named Name
}
int main()
{
func();
}
When i call func
, then in the statement std::cout << sizeof(Name) << std::endl;
, Name
refers to the int
Name
and not class named Name
. Why is this so? I expected that this would give me ambiguity error because there are two(different) entities with the same name. But the program works without any error and sizeof
is applied to int Name
instead of class named Name
. I have read about function overloading in the books. But not about this kind of overloading. What is it called and what is happening here.
PS: I know that i can write std::cout<< sizeof(class Name);
where sizeof
will applied to the class named Name
instead of variable int Name
. Also, the example is for academic purposes. I know that use of global variable should be avoided. The question is not about how to solve this(say by not using same name for those two entities) but about what is happening.
When a class and a variable of the same name are declared in the same scope, then the variable name hides the class name whenever name lookup would find both of them. Looking at [basic.scope.hiding]/21 of the post-C++20 standard draft:
If a class name ([class.name]) or enumeration name ([dcl.enum]) and a variable, data member, function, or enumerator are declared in the same declarative region (in any order) with the same name (excluding declarations made visible via using-directives ([basic.lookup.unqual])), the class or enumeration name is hidden wherever the variable, data member, function, or enumerator name is visible.
I think this behavior, instead of making it an error to declare both a class and a variable of the same name in the same scope, was chosen for compatibility with C. In C the names of struct
s are in a separate namespace from variable names, so they are never ambiguous. For example with
int Name = 0;
struct Name
{
int x[2];
};
in C, whenever you write just Name
it refers to the variable. If you want to refer to the type you must use struct Name
. C++ eliminates the requirement to use the struct
prefix to refer to unambiguous struct
s, but with the rules as they are, name lookup for both Name
and struct Name
will have the same results in C and C++.
1: Note that there was significant rework of the wording for name lookup in the current standard draft for C++23, but it should have the same effect