考虑这个代码示例:
#include <iostream>
namespace /* unnamed namespace */
{
struct Foo
{
int a;
int b;
};
}
struct Boo
{
Foo Foo; /* field name same as field type */
int c;
void print();
};
void Boo::print()
{
std::cout<<"c = "<<c<<std::endl;
std::cout<<"Foo "<<Foo.a<<" "<<Foo.b<<std::endl;
}
int main()
{
Boo boo;
boo.c=30;
boo.Foo.a=-21;
boo.Foo.b=98;
boo.print();
return 0;
}
Clang可以正确编译它。
Debian clang版本3.5.0-9(标签/ RELEASE_350 / final)(基于LLVM 3.5.0)
Microsoft cl.exe编译它没有错误。 (我不记得版本。我使用VS 2012)
GCC:gcc版本4.9.2(Debian 4.9.2-10):
main.cpp:14:6: error: declaration of ‘{anonymous}::Foo Boo::Foo [-fpermissive]
Foo Foo; /* field name same as field type */
^
main.cpp:5:9: error: changes meaning of ‘Foo’ from ‘struct {anonymous}::Foo’[-fpermissive]
struct Foo
^
编译器的良好行为是什么?为什么GCC无法编译它,但是clang和cl.exe呢? C ++标准是什么意思?
答案 0 :(得分:4)
两者都是正确的。按§3.3.7/ 1
以下规则描述了在类中声明的名称范围。
[..]
- 醇>
类
N
中使用的名称S
应在其上下文中引用相同的声明,并在S
的已完成范围内重新评估。违反此规则无需诊断。
没有义务给出错误,gcc选择并且铿锵地选择不这样做。它符合两种方式。