3

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.

5
  • This does not have anything to do with overloading. (The Standard: 'Each of two or more entities with the same name in the same scope, which must be functions or function templates, is commonly called an “overload”.') Commented Feb 9, 2022 at 12:31
  • In [basic.lookup.general] of the draft, there is a note that says "A type (but not a typedef-name or template) is therefore hidden by any other entity in its scope.", but the "therefore" seems to refer to the somewhat vague "In certain contexts, only certain kinds of declarations are included." At least it's not obvious to me what those "certain contexts" could be. Commented Feb 9, 2022 at 12:45
  • 1
    @molbdnilo I think "therefore" refers to the second sentence, not the first (otherwise the note would be placed differently). No matter whether the included declarations were restricted or not, if after consideration of any potential restrictions a non-type declaration is left, all type declarations are discarded, thereby hiding them, which also includes the usual unrestricted name lookup. Commented Feb 9, 2022 at 13:06
  • @user17732522 I would say that it refers to the whole item, and the second sentence's "[...] any such restriction [...]" in turn refers to "certain contexts" without so much as a hint as to the nature of those contexts. (It is a draft though, so a certain vagueness must be expected.) Commented Feb 9, 2022 at 13:22
  • 2
    Dup of What happens when a class and a function have the same name? and/or stackoverflow.com/questions/34839886/… Commented Feb 9, 2022 at 14:58

1 Answer 1

5

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 structs 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 structs, 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

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

Comments

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.