Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
225 views
in Technique[技术] by (71.8m points)

c++ - Injected class name compiler discrepancy

Consider this code:

struct foo{};

int main() {
    foo::foo a;
}

I would expect this to be well-formed, declaring a variable of type foo by the rule in [class]/2 (N4140, emphasis mine):

A class-name is inserted into the scope in which it is declared immediately after the class-name is seen. The class-name is also inserted into the scope of the class itself; this is known as the injected-class-name. For purposes of access checking, the injected-class-name is treated as if it were a public member name.

clang 3.6.0 agrees with me, compiling the above code with no applicable warnings with -Wall -pedantic.

gcc 5.2.0 disagrees, providing the following error message:

main.cpp: In function 'int main()':
main.cpp:5:5: error: 'foo::foo' names the constructor, not the type
   foo::foo a;

The above holds no matter how deep the nesting of injected class names, e.g. foo::foo::foo::foo.

Is there a rule which forces that construct to be interpreted as a constructor in that context, or is this agcc bug? Or am I interpreting the standards quote incorrectly?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It appears that clang is wrong in this case. The relevant exception I was looking for is in [class.qual]/2:

2 In a lookup in which function names are not ignored and the nested-name-specifier nominates a class C:

  • (2.1) if the name specified after the nested-name-specifier, when looked up in C, is the injected-class-name of C, or

  • [...]

the name is instead considered to name the constructor of class C.

The standard has a near-equivalent (non-normative, obviously) example:

struct A { A(); };
struct B: public A { B(); };

A::A() { }
B::B() { }

B::A ba;// object of type A
A::A a;// error, A::A is not a type name
struct A::A a2;// object of type A

However, clang actually issues a correct diagnostic in this case:

error: qualified reference to 'A' is a constructor name rather than a type wherever a constructor can be declared

Perhaps clang interprets the line In a lookup in which function names are not ignored as In a lookup in which a constructor declaration is valid, but that doesn't seem to be a correct interpretation.

There is an existing bug for this in the clang bugzilla.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...