在堆栈溢出时,有许多人混淆了将弱符号链接到静态库。简而言之,当只使用对象文件(而不使用库(时,弱文件将始终被强文件覆盖为符号。但是当使用静态库时,事情会变得混乱。我不会在这里解释差异,但堆栈溢出上有一些线程可以解释它们。我的问题是他们为什么会这样?目前,这对我来说毫无意义。
编辑
链接到相关堆栈溢出线程:
- 1
- 2
- 3
- 4
- 5
混淆的解释:
弱的目的(在我看来(是为了让用户可以在需要时(或为了语言内部使用,例如inline
(用自己的函数覆盖函数,但当库创建者在同一(或底层(档案中覆盖函数时,它不会被覆盖,链接器只需选择它看到的第一个定义。这与";扁平的";(无图书馆的(结构。
弱的目的是(在我看来(,这样用户就可以在需要时(或为了语言内部使用,例如内联(用自己的函数覆盖函数,
是和否。我会缩小范围并改变重点:弱符号的目的是让库可以提供其他库函数使用的某些函数的默认实现,但也允许使用该库的程序替换自己的实现。
此外,尽管这并不排除静态库的使用,但它主要用于动态库,因为在链接静态库时,不需要弱符号。另一方面,共享库需要以不同的方式构建,并得到动态链接器的支持,以允许这样的替换。
但当库创建者覆盖同一(或底层(存档内的函数时,它不会被覆盖,链接器只需选择它看到的第一个定义。
然后呢?静态库的创建者可以控制其内容,包括它们的顺序。如果它们的意思是为给定的符号提供一个特定的强定义,那么将该符号的任何其他外部定义放入同一库至少是浪费。
是的,静态链接器仍然可以在这一点上为库作者提供支持,但这种场景并不是弱符号设计支持的场景,那么为什么链接器维护人员要花费精力来实现它,并承诺无限期地维护它呢?
这与";扁平的";(无图书馆的(结构。
这取决于您如何在";扁平的";案例此外,将一组(仅(对象文件链接到一个完整的程序中仍然不是弱符号所支持的场景。
他们为什么会这样?
如果你想要一个权威的答案,你必须问设计者,但我认为GCC工具链的作者和维护者认为,你所问的静态链接行为是工具复杂性和弱符号的理想语义之间的合理折衷。他们很可能在这一领域受到SUN工具的影响,而SUN工具可能实际上是做出决定的地方。
所选择的细节很好地满足了弱符号的预期目的,我很有信心,一个包含同一符号的弱定义和强定义的库不在指导工具设计的用例中。直接链接对象文件的行为与从静态库链接它们的行为不同,这可能被认为是不一致的,但这是过程的心理模型的问题。无论如何,我倾向于认为当时提出的问题是";用户最可能的意思是什么&";,链接多个对象文件(可能全部由程序/库作者提供(和链接静态库(通常由第三方提供(的答案是否相同,这一点并不清楚。