链接含多定义符号的静态库的程序是否具有定义行为?
静态库多定义符号与ODR规则的疑问
对于每个被odr-used的非内联函数或变量,整个程序(包括所有标准库和用户定义库)中必须有且仅有一个定义。编译器无需诊断此类违规,但违规程序的行为是未定义行为。
核心疑问
- 链接了包含多定义符号的静态库的程序,是否因违反ODR规则而属于未定义行为?
- 还是程序行为是确定的——因为链接器会选择其中一个符号,且链接器的行为有明确定义?链接器处理静态库的规则定义在哪里?
解答
ODR违规即触发未定义行为
只要程序中存在被odr-used的非内联函数或变量的多个定义,无论这些定义来自静态库还是普通目标文件,都直接违反了One Definition Rule,程序行为属于未定义行为。C++标准对此有明确规定,编译器/链接器无需强制诊断,但违规程序的运行结果完全不可靠。链接器的选择是实现行为,而非标准规定
链接器通常会在遇到多定义符号时选择其中一个(比如GNU链接器默认选取第一个找到的定义,仅发出警告),但这只是特定链接器的实现细节,并非C++标准要求的统一行为。不同链接器、同一链接器的不同配置都可能做出不同选择,导致程序行为出现差异,完全不具备可移植性和确定性。链接器规则的定义位置
链接器处理静态库的具体规则,由其自身的实现文档定义(比如GNU ld的官方文档、MSVC链接器的微软文档),不属于C标准的范畴。C标准仅要求程序遵守ODR规则,对链接器如何处理违规场景没有强制约束。
内容的提问来源于stack exchange,提问作者Benjamin Bihler
相关产品推荐
相关产品推荐

