同一类的几个定义

时间:2009-03-30 12:26:43

标签: c++ linker

使用MSVC ++ 2005时,我注意到如果多次定义同一个类,程序仍然很乐意链接,即使在最高警告级别。我觉得这很令人惊讶,为什么这不是一个错误?

module_a.cpp:

#include <iostream>
struct Foo {
  const char * Bar() { return "MODULE_A"; }
};
void TestA() { std::cout << "TestA: " << Foo().Bar() << std::endl; }

module_b.cpp:

#include <iostream>
struct Foo {
  const char * Bar() { return "MODULE_B"; }
};
void TestB() { std::cout << "TestB: " << Foo().Bar() << std::endl; }

main.cpp中:

void TestA();
void TestB();
int main() {
  TestA();
  TestB();
}

输出是:

TestA: MODULE_A
TestB: MODULE_A

2 个答案:

答案 0 :(得分:3)

这是一个错误 - 代码破坏了C ++ One Definition Rule。如果你这样做,标准说你得到了未定义的行为。

代码链接,因为如果你有:

struct Foo {
  const char * Bar() { return "MODULE_B"; }
};

在两个模块中都不存在ODR违规 - 毕竟,这基本上是#including标头所做的。违规是因为您的定义不同(另一个包含字符串“MODULE_A”),但链接器(仅查看类/函数名称)无法检测到这一点。

答案 1 :(得分:0)

编译器可能会认为该对象除了在Test#()函数中使用之外没用,因此可以内联整个对象。这样,链接器永远不会看到任何一个类甚至存在!不过只是一个想法。

或者不知何故,TestA和类Foo [#]之间的链接将在编译中完成。如果链接器正在寻找类Foo(多重定义),那么会发生冲突,但链接器根本不会查找它!

如果在未启用优化的情况下在调试模式下进行编译,是否存在链接错误?