What happens when a class and a function have the same name?
Asked Answered
S

3

26
#include <iostream>
using namespace std;

struct test
{
    test(){cout<<"class"<<endl;}
};
void test(){cout<<"function"<<endl;}

int main()
{
    test();
    return 0;
}

Output:

function  

(VS2013 ang gcc 4.8.1)

Why function is selected? Isn't it ambiguity?

Sateen answered 13/10, 2014 at 14:6 Comment(3)
i think the compiler picks the function because a class is never called with its base name.. if you remove the void test(), you may likely get an undefined function.... it is not ambigue because the two are always called by diffent contexts...Nammu
Check this question, it is similar: #7764302 @LeonardoBernardini You do not get undefined function if you remove void test(), because then the compiler will create a new test object but not assign it anywhere.Jacey
you can reach your class with struct test t{}; syntaxEinhorn
J
25

This is called name hiding and described in

3.3 Scope [basic.scope]

3.3.1 Declarative regions and scopes [basic.scope.declarative]

4) Given a set of declarations in a single declarative region, each of which specifies the same unqualified name,
— they shall all refer to the same entity, or all refer to functions and function templates; or
— exactly one declaration shall declare a class name or enumeration name that is not a typedef name and the other declarations shall all refer to the same variable or enumerator, or all refer to functions and function templates; in this case the class name or enumeration name is hidden (3.3.10). [...]

emphasis mine.

Note that changing the order of declaration doesn't affect the outcome:

void test(){cout<<"function"<<endl;}

struct test
{
    test(){cout<<"class"<<endl;}
};

int main()
{
    test();
    return 0;
}

still prints out function.

In case it isn't obvious, don't do this :)

Joker answered 13/10, 2014 at 14:15 Comment(2)
You should probably point out that this is a hack, for reasons of C compatibility, and that you probably don't want to use it in actual code.Hedvig
You didn't know that it was for C compatibility, or you didn't know that it was a bad idea:-). The real reason it's there is to support the Posix function stat (which has an out parameter struct stat*); in C, you need the struct, and names after the struct are looked up in a different namespace than the others. The somewhat awkward rules in C++ are an attempt to support this, while still allowing the use of C libraries like Posix. (And I'm sure that this was documented in some early specifications, maybe the ARM.)Hedvig
D
10

From N3485 §3.3.10 [basic.scope.hiding]/2:

A class name (9.1) or enumeration name (7.2) can be hidden by the name of a variable, data member, function, or enumerator declared in the same scope.

Therefore, the function takes precedence over the class.

As mentioned in the comments, the class is still accessible via the class or struct keyword. If the class took precedence, the function would be unreachable.

Dandiprat answered 13/10, 2014 at 14:15 Comment(0)
S
-5

I'm not certain either of the previous responses are the "why" for your particular instance.

Don't get me wrong; They are true and accurate.

I just think it's simpler.

In your example, you never instantiate the struct.

In other words, you declared it, but you never used it.

Since you never referenced it, it is never called.

Name precedence and such don't really apply here, since you never instantiated the struct.

Hope this helps,

-john

Strict answered 13/10, 2014 at 17:14 Comment(2)
You are supposed to cite any source or documentation to reason what you think, or provide any evidence to prove it correct. In this answer you failed to do so.Tigre
That answer is not even logical in itself: The class is never instantiated because the precedence rules cited in the other answers require that the function is called. If the precedence rules where the other way round, a temporary object would be instantiated and the constructor would be called. So saying "precedence and such don't apply, because the struct is not instantiated" is just plain wrong.Lampas

© 2022 - 2024 — McMap. All rights reserved.