【发布时间】:2017-04-18 04:01:02
【问题描述】:
如果我有一个文件foo.cpp,代码如下:
class Foo {
};
class Foo {
};
int main() {
return 0;
}
那么我自然会得到error: redefinition of 'Foo'。但是,如果我有 foo.cpp 和
class Foo {
};
int main() {
return 0;
}
和bar.cpp一起
class Foo {
};
尽管class Foo 在整个程序中被定义了两次,但整个过程编译得很好。
如果我将int something; 放在全局命名空间的两个文件中,那么我会得到一个链接器错误(特别是duplicate symbol),但对于类定义,这永远不会发生。
我知道 int doIt(); 这样的函数声明可以在两个 cpp 文件中重复,但是 定义,例如int doIt() {} 不能。现在在第一个编译器错误中(class Foo{}; 在一个 cpp 文件中有两次),它说redefinition of foo,所以class Foo{}; 是一个定义。那么为什么与函数不同,它可以在一个程序中定义两次呢?
编辑:根据this website,命名类具有外部链接。那么为什么class Foo 在两个 cpp 文件中没有冲突呢?
EDIT2: 根据上面链接的网站,命名类不仅有外部链接,静态成员也有。然而这一切都编译得很好:
foo.cpp:
class Foo {
public:
int foo();
static int x;
};
int Foo::foo() {
return 5;
}
int main() {
return 0;
}
bar.cpp:
class Foo {
public:
int foo(int);
static bool x;
};
int Foo::foo(int i) {
return i * 2;
}
不仅Foo::foo 被重新定义为不同的签名,而且Foo::x 是不同的类型。这两个都应该有外部链接,但是这个代码是好的。
【问题讨论】:
-
那是什么编译器?
-
这个问题has been discussed here, tl;dr;当具有相同名称的类(枚举、联合等)在不同的翻译单元中单独定义时,它们具有内部链接或没有链接,因此不会发生错误。请注意,接受的答案是错误的,而获得更多支持的答案是正确的。
-
@ΦXocę웃Пepeúpaツ Apple LLVM 版本 7.3.0 (clang-703.0.31)
-
您是否对标准的相应规则感兴趣,或者这样做的动机?
-
@VTT 你链接到了正确的问题,指出了正确的答案,然后总结错了。