我对以下情况感到非常困惑:
我有一个Linux项目(用c编写),该项目使用静态库A获取可执行文件。在此静态库A中,有一个c代码,该代码从Linux include调用sem_init。 .c文件中包含semaphore.h,该文件使用GCC编译而没有警告。我使用ld链接器。
一切都很好,直到我无意中向项目中添加了一个新模块(已编译到静态库B中)。新代码具有一个具有相同名称(sem_init)但签名不同的函数。来自A的代码不包含来自B的.h文件,该文件定义了新的sem_init()。
现在,在将库B添加到编译后,我看到从库B调用了新的sem_init,而不是semaphore.h中的sem_init。
我知道使用相同名称调用函数是一个糟糕的主意,但是在大型项目中,它可能会无意间发生。
问题:为什么会这样???为什么链接器选择了新的sem_init?为什么我没有收到多定义链接错误?
我对以下情况感到非常困惑:我有一个Linux项目(用c编写),该项目使用静态库A获取可执行文件。在此静态库A中,有一个c代码,...
当链接器链接静态库时,它仅在其中查找未定义的符号,如果找到定义,则将其链接并解析该符号。 sem_init
恰好来自B
,该链接在-lc
(也实现POSIX sem_init
的GNU C标准库)被链接之前被链接,因此链接器从sem_init
拾取B
,然后从不再次寻找sem_init
,这就是为什么不会出现多个符号定义错误的原因。