Declaration of method changes meaning of symbol
Asked Answered
D

1

23

For the following code:

struct foo {};

struct A
{
    typedef foo foo_type;

    void foo();
};

GCC gives a compiler error:

test.cpp:7:14: error: declaration of 'void A::foo()' [-fpermissive]
     void foo();
              ^
test.cpp:1:8: error: changes meaning of 'foo' from 'struct foo' [-fpermissive]
 struct foo {};
        ^

But clang accepts it without compiler errors. Who is right?

Note that if the typedef is removed, or changed to typedef ::foo foo_type, both gcc and clang accept the code.

Drift answered 20/3, 2013 at 23:54 Comment(6)
The real question is: Why is Clang always right?Dialect
when there's no typedef then it is not strangeMegaron
@cf16: I didn't say it was. I just wanted to point out that, in spite of the error not mentioning the typedef, the typedef has something to do with the error.Drift
Try it with typedef ::foo foo_type; instead.Rabbitry
@user315052: That also makes the error go away. My question still stands though.Drift
You can also "solve" it with typedef struct foo foo_type;. And the behaviour changes if you swap the typedef and the function declaration.Dialect
B
20

gcc is correct, but clang is not required to give a diagnostic (3.3.7):

A name N used in a class S shall refer to the same declaration in its context and when re-evaluated in the completed scope of S. No diagnostic is required for a violation of this rule.

This is because of how class scope works. The foo of void foo(); is visible within the entire scope of the class A, so the declaration of void foo(); changes the meaning of foo in the typedef from referring to struct foo to the name of the function foo.

Brimmer answered 21/3, 2013 at 3:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.