You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

跨翻译单元实验inline函数:非inline函数为何优先?是否违反ODR?

关于inline函数跨翻译单元的链接行为与ODR问题

我在跨翻译单元测试inline函数时遇到了如下场景:

// A.cpp
#include <iostream>

void f() {
    std::cout << "Bye" << std::endl;
}
// main.cpp
#include <iostream>

inline void f() {
    std::cout << "Hello" << std::endl;
}

int main() {
    f();
    return 0;
}

使用g++ main.cpp A.cpp编译链接后运行,控制台输出“Bye”。以下是对问题的解答:

一、为什么输出“Bye”而非“Hello”?

这是链接器对符号优先级的处理逻辑导致的:

  • C++中,普通非inline函数属于强符号(外部链接属性,整个程序中理论上只能存在一个定义);而inline函数默认被标记为弱符号(允许多个翻译单元存在定义,但链接时会被同名强符号覆盖)。
  • 你的代码里,A.cpp中的f()是非inline的强符号,main.cpp中的inline f()是弱符号。链接器合并目标文件时会优先选择强符号的定义,所以最终程序调用的是A.cpp里的f(),输出“Bye”。

二、这种情况是否违反One-Definition Rule(ODR)?

严格来说,这种情况完全违反了ODR:

  • ODR对inline函数的明确要求是:如果一个inline函数在多个翻译单元中定义,那么所有定义必须完全一致——不仅函数体内容要token-for-token匹配,每个定义都必须带有inline声明,且依赖的所有实体也需一致。
  • 你的代码中,A.cpp的f()没有inline声明,且函数体与main.cpp的版本完全不同,这直接违反了ODR规则。但ODR违反属于C++标准中的未定义行为,编译器和链接器不一定会主动报错,而是可能按各自的逻辑处理(比如这里的强符号覆盖弱符号),但这种行为不可移植、不能依赖。

内容的提问来源于stack exchange,提问作者Broseph_Stally

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 00:34:51