如何使ld处理将定义的结构/类重叠为错误?

时间:2012-05-11 11:04:43

标签: c++ gcc ld multiple-definition-error

编辑 - 澄清我的问题的目标: 我失去了大量的时间来诊断我希望链接器报告的问题,这是由于一种公认的糟糕的编程风格造成的,例如在将一个代码块从一个编译单元复制粘贴到另一个编译单元,然后对其进行修改。

我正在寻找一种在编译/链接时检测此问题的方法。

在此设置中:

A.H

void foo();

A.cpp

struct A { 
  int values[100];
  A(){ 
    std::cout << __FILE__ << ": A::A()\n";
}};
void foo(){ 
   A a;
}

的main.cpp

#include "A.h"
struct A { 
  double values[100];
  A(){ 
  std::cout << __FILE__ << ": A::A()\n";
}};
int main(){ foo(); }
// void foo(){} ===> this would cause a linker error

我希望链接器报告结构A或至少构造函数A::A()被定义两次。

然而,g ++ 4.4链接就好了。运行代码表明,在这种情况下,链接器选择使用A.cpp。{/ p>中的A

$ g++ -Wall A.cpp main.cpp && ./a.out
A.cpp:3
A.cpp:7
A.cpp:3

当两个目标文件中存在函数 foo()时,链接器会报告多重定义,但对于结构,它不会。

编辑:刚使用nm -C *.o找到A.o和main.o都将A::A()定义为弱符号。这使得它可以从具有相同名称的符号池中“选择”。也许这个问题可以改为“如何让编译器生成符号?”......

00000000 W A::A()

如何检测此问题?

2 个答案:

答案 0 :(得分:2)

  

也许问题可以改为“如何让编译器生成强符号?”......

尝试限制inline功能的使用:

struct A {
    A();
};

// Inside A.cpp
A::A() { 
    std::cout << __FILE__ << ": A::A()\n";
}

实现更有可能报告未声明为inline的函数的ODR违规(包括那些隐式声明为inline的函数,就像内部定义的成员一样一个类定义),虽然严格来说,这种诊断从不需要。

答案 1 :(得分:0)

这不是问题,也不是重新定义。这就是C ++的工作原理。想一想 - 你把类定义放在标题中(暴露声明只是很少见)。标题几乎被复制粘贴到使用它们的每个翻译单元中。在多个TU中具有多个相同类的定义不能是错误。所以,这不是要解决的问题。

如果在同一名称下定义了不同的类,编译器/链接器应该会抱怨。