外部符号如何解析?

问题描述:

我已经​​& 37064544_p2.cpp了同样内容如下两个文件:外部符号如何解析?

int add(int x,int y) 
{ 
return x+y; 
} 

我使用

g++ -c 37064544_p2.cpp -o 37064544_p2.o 
g++ -c 37064544_p2.cpp -o 37064544_p2.o 

编译它们,并将它们添加到使用

ar -rsc lib37064544pf.a 37064544_p1.o 37064544_p2.o 

和存档

$ nm -s lib37064544pf.a 

给我:

Archive index: 
_Z3addii in 37064544_p1.o 
_Z3addii in 37064544_p2.o 

37064544_p1.o: 
0000000000000000 T _Z3addii 

37064544_p2.o: 
0000000000000000 T _Z3addii 

$ ar -t lib37064544pf.a 

给我

37064544_p1.o 
37064544_p2.o 

我有调用_Z3addii函数与

编译驱动程序

结果是

Sum : 11 

问题

  1. 如何符号_Z3addii解决?

    • 是否根据存档索引?
    • 是否按照我们使用ar来填充存档的顺序?
  2. 如何更改此订单?

  3. 如何防止ar重复符号?

编译:克++ 4.6.3

+1

Hrmm,我刚刚在叮当中尝试过。如果直接使用两个.o文件进行编译,则会出现重复符号错误,但如果将两个.o文件放入.a文件并进行编译,则不会出现错误。我一直认为.a只是一个方便的方式来拥有一堆.o文件,但它在某些方面似乎有所不同。 – xaxxon

+1

ar的'r'标志似乎意味着稍后添加到存档中的东西将替换较早的东西,尽管使用q运行它,但我仍然无法获得重复的符号错误。当链接器遇到它正在寻找的符号的第一个条目时,链接器是否停止查看单个文件? – xaxxon

+0

@xaxxon:'如果你直接编译两个.o文件,你会得到一个重复的符号错误,'。是的,但我并不总是赞成这个为了方便起见 – sjsam

如何符号_Z3addii解决?

实现*为所欲为,你违反了one definition rule

实际上,它会在第一次匹配后停止查找任何给定的符号,这大概遵循文件插入到存档的顺序。

如何更改此订单?

随着ar可以使用a(后)和b(前)修饰符存档插入,你还是违反了ODR尽管当他们来定位目标文件。

如何防止ar重复符号?

你不能因为据我所知,ar是比较愚蠢的和充分的理由为一些语言都允许相同的符号,这就是为什么你没有任何错误与归档链接时(无ODR违规需要诊断)。

您可以强制ld阅读整个归档

g++ -static 37064544driver.cpp -o 37064544driver.elf -L. \ 
-Wl,--whole-archive -l37064544pf -Wl,--no-whole-archive 

或者,如果有任何重复,你可以做的部分链接,而不是传统的归档,这将给你一个错误

ld -r -o lib37064544pf.a 37064544_p1.o 37064544_p2.o 
+0

Thankyou。我同意我违反了ODR,但是就这个例子而言,这是有意的,但是在归档目标代码时感兴趣的是更大的感谢,谢谢关于部分链接的观点。我还会考虑将对象添加到不同的库中,并按照我想要的顺序链接它们。 – sjsam