内联函数链接

Cri*_*ina 19 c++ inline function

我无法理解以下行为:一个标题包含一些基本类型,另一个标题我在几个函数中使用这些类型.之后我开始根据我定义的类型和函数构建类.在函数头中,如果我留下以下签名:

void whateverFunction(parameters)
Run Code Online (Sandbox Code Playgroud)

链接器指出whateverFunction有多个定义.现在如果将其更改为:

inline void whateverFunction(parameters)
Run Code Online (Sandbox Code Playgroud)

联系问题已经消失,所有编译和链接都很好.我所知道的内联是它用它的代码替换每个函数调用,而不是它非常暗,所以我的问题是:

链接器如何处理C++中的内联函数?

Chu*_*dad 26

当标题中的函数不是内联函数时,此函数的多个定义(例如,在多个转换单元中)违反了ODR规则.

默认情况下,内联函数具有外部链接.因此,作为ODR规则的结果(如下所示),这样的多个定义(例如,在多个翻译单元中)是好的:

$ 3.2/5-"类类型(第9章),枚举类型(7.2),带内部链接的内联函数 (7.1.2),类模板(第14章),非静态函数模板可以有多个定义(14.5.6),类模板的静态数据成员(14.5.1.3),类模板的成员函数(14.5.1.1),或未指定某些模板参数的模板特化(14.7,14.5.5)一个程序规定每个定义出现在不同的翻译单元中,并且如果定义满足以下要求.给定这样一个名为D的实体在多个翻译单元中定义,那么

- D的每个定义应由相同的令牌序列组成; 和[...]

链接器如何处理内联函数是一个非常多的实现级细节.只需知道实施在ODR规则的限制范围内接受了多种定义即可

请注意,如果标头中的函数声明更改为"static inline ....",则内联函数显式具有内部链接,并且每个翻译单元都有自己的静态内联函数副本.

  • 在现代编译器中,可以看到`inline`作为关键字以允许多个定义而不是优化提示.编译器可以决定不内联内联函数,链接器可以跨编译单元选择任何一个.程序员应确保跨编译单元的内联函数是相同的.否则会出现未定义的行为. (4认同)

Mar*_*tos 9

链接器可能根本看不到内联函数.它们通常直接编译到调用它们的代码中(即代码用于代替函数调用).

如果编译器选择不内联函数(因为它只是一个提示),我不确定,但我认为编译器将其作为普通的非内联函数发出并以某种方式对其进行注释,以便链接器只选择第一个副本它看到并忽略了其他人.