当一个符号在多个目标文件(.o)里同时出现时, LD报错. 提示符号多重定义.
当一个符号在多个静态库(.a)里同时出现时,或多个静态库和一个目标文件同时出现时, LD不报错, 以第一个遇到的为准. 并且不会有任何warning提示 !!! 这个规则可能导致很多意想不到的问题!!!
补充一些:
GCC/LD在
1.做符号解析时,会把找到的第一个定义的代码链接进来(已经找到了就不再考虑后续的)
2.做Object链接时(*.o文件),每一个目标文件要做reloc操作,找到的第一个定义优先处理,再遇到一个相同的定义,就报"multip-definition 错误",这个可以通过-Wl,'-z muldefs'来解决,
-z muldefs会让ld在遇到重复定义时候,只处理第一个定义。
在运行时刻,如果:
1.存在多个相同的动态库名,则根据ldconfig中配置的库查找路径,先找到哪个就用哪个。如果机器中存在不同版本的动态库,则可能会用上错误的库,而从我们的代码中是检查不出错误的,
只能优先做"ldconfig -p | grep 库名"的检查,干掉一个不用的库就可以。
2.如果多个不同的动态库,拥有相同的全局变量名,则最后加载的动态库中的全局变量会冲掉之前加载的全局变量,导致结果异常(程序正常工作)
下面这篇文章对链接处理的说明的比喻挺贴切的:
另外,对比VC++的行为,是不一样的,VC++在发现安多个依赖库中有同名符号时,会符号重定义,而不是默认的选择一个,同时,VC++还提供了当符号重定义时忽略制定的库的能力