Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 内联函数链接_C++_Function_Inline - Fatal编程技术网

C++ 内联函数链接

C++ 内联函数链接,c++,function,inline,C++,Function,Inline,我无法理解以下行为:一个标题包含一些基本类型,另一个标题中我在几个函数中使用这些类型。之后,我开始根据定义的类型和函数构造类。在函数标题中,如果我留下以下签名: void whateverFunction(parameters) 链接器指出whateverFunction有多种定义。现在,如果将其更改为: inline void whateverFunction(parameters) 链接问题消失了,所有的编译和链接都很好。关于内联,我所知道的是它用它的代码替换每个函数调用,而不是它是一个

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

void whateverFunction(parameters)
链接器指出whateverFunction有多种定义。现在,如果将其更改为:

inline void whateverFunction(parameters)
链接问题消失了,所有的编译和链接都很好。关于内联,我所知道的是它用它的代码替换每个函数调用,而不是它是一个非常黑暗的过程,所以我的问题是:


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

> P>链接器可能根本看不到内联函数。它们通常直接编译成调用它们的代码(即,使用代码代替函数调用)


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

当标头中的函数未内联时,那么,此函数的多个定义(例如,在多个翻译单元中)违反了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规则的限制范围内接受这样的多个定义就足够了


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

内联只是掩盖了问题。具有多个定义指出了某个地方的问题

只是在使用标题时要小心。别忘了: ->以避免多重包含。
-不要使用间接包含:如果在文件中使用类型,请添加相应的头,即使同一文件中的另一个头包含该类型。

有关详细信息,请参阅,尤其是“一个定义”规则中的部分。默认情况下,内联函数具有外部链接。注意:我发现此语句有误导性。内联代码根本没有链接,至少n函数名下的ot。请参阅。在现代编译器上,可以将
inline
视为关键字,以允许多个定义,而不是优化提示。编译器可以决定不内联内联函数,链接器可以跨编译单元选择任何一个。程序员应确保跨编译器的内联函数在单位上是相同的。否则会出现未定义的行为。您可以包含来自两个不同翻译单位的相同标题,而警卫不会帮助您。