编译器如何处理内联导出函数?

and*_*ykx 5 c++ compiler-construction export inline

如果头文件包含函数定义,则编译器可以内联它。如果导出了函数,则在链接过程中也必须使客户机可以使用该函数的名称和实现。编译器如何做到这一点?它是否内联函数并为外部调用者提供实现?

考虑Foo.h:

class Foo
{
    int bar() { return 1; }
};
Run Code Online (Sandbox Code Playgroud)

Foo :: bar可以内联或不在库foo.so中。如果另一段代码包含Foo.h,它是否总是创建自己的Foo :: bar副本,无论是否内联?

Pot*_*ter 2

头文件只是复制粘贴到源文件 \xe2\x80\x94 中,仅此而已#includeinline仅当使用该关键字声明或在类定义内定义时,函数才有效,并且inline仅是一个提示;它不会强迫编译器生成不同的代码或禁止您做任何您可以做的事情。

\n\n

您仍然可以获取函数的地址inline,或者等效地,正如您提到的,导出它。对于这些用途,编译器只是将其视为非,inline并使用一个定义规则(该规则表示用户不能将两个定义应用于同一函数、类等)来“确保”该函数被定义一次并且仅导出一份副本。通常情况下,所有来源中只允许有一个定义;内联函数必须有一个定义,该定义在使用它的每个源中都精确重复。

\n\n

以下是标准对inline extern函数的规定 (7.1.2/4):

\n\n
\n

内联函数应在使用该函数的每个翻译单元中定义,并且在每种情况下都应具有完全相同的定义 (3.2)。[注意:在其定义出现在翻译单元中之前,可能会遇到对内联函数的调用。] 如果具有外部链接的函数在一个翻译单元中声明为内联,则应在它出现的所有翻译单元中声明为内联;无需诊断。具有外部链接的内联函数在所有翻译单元中应具有相同的地址。外部内联函数中的静态局部变量始终引用同一个对象。外部内联函数中的字符串文字是不同翻译单元中的同一对象。

\n
\n