内联关键字与标题定义

Sir*_*lot 26 c++ optimization inline

在函数之前使用inline关键字和在头文件中声明整个函数之间有什么区别?

所以...

int whatever() { return 4; }
Run Code Online (Sandbox Code Playgroud)

VS

.H:

inline int whatever();
Run Code Online (Sandbox Code Playgroud)

的.cpp:

inline int myClass::whatever()
{
    return 4;
}
Run Code Online (Sandbox Code Playgroud)

就此而言,这是做什么的:

inline int whatever() { return 4; }
Run Code Online (Sandbox Code Playgroud)

Mat*_* M. 29

有几个方面:

语言

  • 当一个函数用inline关键字标记时,它的定义应该在TU中可用,或者程序格式错误.
  • 隐式标记在类定义中定义的任何函数inline.
  • 标记inline(隐式或显式)的功能可以在几个TU(关于ODR)中定义,而对于常规功能则不是这种情况.
  • 模板功能(不完全专业化)得到与之相同的处理inline.

编译器行为

  • 标记的函数inline将在每个目标文件中作为弱符号发出,这可能会增加它们的大小(查找模板膨胀).
  • 而编译器实际内联调用(即,在使用点复制/粘贴代码而不是执行常规函数调用)完全由编译器自行决定.关键字的存在可能会或不会影响决策,但它最多只是一个提示.

链接器行为

  • 弱符号合并在一起,在最终库中出现一次.一个好的链接器可以检查多个定义是否同意,但这不是必需的.

  • 你是什​​么意思"TU"和"ODR"? (6认同)
  • @WiSaGaN:TU =翻译单位:粗略地说,是预处理的源文件.ODR =一个定义规则:要求所有函数/类的定义在字符级别上与TU相同. (4认同)

jus*_*tin 10

inline,你很可能会结束与多个导出的符号,如果函数在命名空间或全球范围内声明的(在链接错误结果).

但是,对于一个类(如您的示例所示),大多数编译器隐式将该方法声明为内联(-fno-default-inline将在GCC上禁用该默认值).

如果将函数声明为内联函数,编译器可能希望在转换中看到它的定义.因此,您应该在定义可见的时间保留它.

在更高级别:更多翻译经常可以看到类声明中的定义.这可以带来更好的优化,并且可以增加编译时间.

除非手动优化和快速编译都很重要,否则最近在类声明中使用关键字是不常见的.


Mik*_*our 10

其目的inline是允许在多个转换单元中定义函数,这对于某些编译器能够在任何使用它的位置进行内联都是必需的.它应该在头文件中定义函数时使用,尽管在定义模板或类定义中的函数时可以省略它.

在标题中定义它inline是一个非常糟糕的主意; 如果你包含多个翻译单元的标题,那么你就打破了一个定义规则; 您的代码可能不会链接,并且可能会出现未定义的行为.

在标题中声明它inline但在源文件中定义它也是一个非常糟糕的主意; 该定义必须在使用它的任何翻译单元中可用,但通过在源文件中定义它,它只能在一个翻译单元中使用.如果另一个源文件包含标题并尝试调用该函数,则您的程序无效.