Home > Software engineering >  Overloading class name with integer variable
Overloading class name with integer variable

Time:02-11

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.

CodePudding user response:

What happens here is "shadowing". The global varible shadows the class of the same name.

What you can do to avoid it is:

  • (don't use global variables)
  • don't give the same name to different entities. Typically naming conventions are different for variables and types (eg name for the variable vs Name for the type).
  • make it explicit that you want to refer to the type via std::cout << sizeof(class Name) << std::endl;
  • if you really want them to have the same name you can place them in different namespaces.

For example:

#include <iostream>

namespace foo {
    int Name = 0;
}

namespace bar {
    class Name {
        int x[2];  
    };
}

namespace baz {
    void func() {
        std::cout << sizeof(foo::Name) << std::endl;
        std::cout << sizeof(bar::Name) << std::endl;
    }
}

int main()
{
    baz::func();
    
}

PS: As mentioned in a comment, this has nothing to do with overloading. Shadowing generally refers to entities having the same name while only one is accessible by that name. Overloading is very different from that, because when you overload a function then typically all the overloads are accessible and overload resolution decides which one to use.

CodePudding user response:

Since you added the language-lawyer tag:

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, see [basic.scope.hiding]/2 of the post-C 20 standard draft. (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.)

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 .

  • Related