为什么链接器链接了错误的功能?

问题描述 投票:0回答:1

我对以下情况感到非常困惑:

我有一个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代码,...

c linux linker linkage
1个回答
0
投票

当链接器链接静态库时,它仅在其中查找未定义的符号,如果找到定义,则将其链接并解析该符号。 sem_init恰好来自B,该链接在-lc(也实现POSIX sem_init的GNU C标准库)被链接之前被链接,因此链接器从sem_init拾取B,然后从不再次寻找sem_init,这就是为什么不会出现多个符号定义错误的原因。

© www.soinside.com 2019 - 2024. All rights reserved.