兼容c ++ 11的编译器总是忽略内联提示吗?

时间:2015-08-17 09:55:04

标签: c++ c++11 inline

old answer上阅读When should I write the keyword 'inline' for a function/method?上写着:

  

据说内联提示您认为函数应该内联到编译器。这可能是在1998年,但十年后编译器不需要这样的提示。更不用说人类在优化代码时通常是错误的,所以大多数编译器都会忽略“提示”。

这个答案是在2009年发布的,所以我想最终解决这个问题:

  1. 现代c ++ 11兼容编译器总是忽略用户指定的inline提示并仅自动执行此操作吗?
  2. 仅提供inline提示以提供向后兼容性吗?
  3. 如果不是1.,那么这个答案是不正确的?

3 个答案:

答案 0 :(得分:6)

  1. 不,他们只是将其解释为标准要求,但有些编译器可能只做那些(根据MSVC基于inline关键字的存在而选择的文档,GCC 5.1.0也采用了决定时考虑inline个关键字。
  2. 不,在链接时也需要内联以避免重复的符号。
  3. inline关键字确实有意义,但不是您可能期望的含义。它并不意味着编译器必须/应该/可能内联扩展函数,编译器可能决定按照它认为合适的方式执行,无论您是否使用inline

    它的意思是你应该并且可以在每个使用它的编译单元中重复函数定义,而不会导致链接错误 - 与static关键字非常相似。

    例如GCC 4.7.2(可能不是最先进的,但仍然是相当现代的编译器)似乎只能解释inline不超过标准规定的内容。如果禁用优化并且启用了优化,它似乎没有内联函数它似乎无论如何都是内联的。唯一的区别是编译器如何处理"概述"函数在不同的情况下,内联它只是丢弃它或处理它以避免链接时重复的符号。

答案 1 :(得分:3)

  
      
  1. 现代c ++ 11兼容编译器是否始终忽略用户指定的内联提示并仅自动执行此操作?
  2.   

C ++ 11与此无关,C ++ 11标准没有改变inline的语义,编译器优化很大程度上与编译的语言版本无关。

  
      
  1. 仅提供内联提示以提供向后兼容性吗?
  2.   

不,inline不是提示,编译器不会“忽略”inline,因为如果这样做,就会出现多个定义错误。编译器赋予inline关键字的含义并不是您似乎理解的含义。这不是一个暗示。

如果编译器无法看到函数定义,则无法对其进行内联(链接时优化会改变它,但LTO的使用还不是很普遍,并且大多数库都不附带允许启用LTO的二进制文件链接时间内联)。

您应该将inline视为“此函数定义在此文件中显示为内联”而不是“应该内联对此函数的调用”。

因此inline关键字对于允许编译器查看多个文件中的函数定义非常有用,这意味着它可以可能,以便通过内联来优化调用。这并不一定比在同一翻译单元中定义的任何其他函数更有可能被内联。

对于从定义标题中的函数的多个翻译单元调用的函数,并使它们inline必要条件,编译器可以内联它们,但它不是足够的(因为编译器根据其他条件建立内联决策)。

这与向后兼容性无关,今天和2009年一样真实。

答案 2 :(得分:2)

C ++ 11编译器遵循内联提示,与C ++ 03或该语言的任何版本相同。

但请注意,inline关键字不是内联提示。提示看起来更像__attribute__((always_inline))

inline关键字(或隐式内联状态,应用于模板等)表示函数是在标头中定义的,因此链接器应该在组合翻译单元时看到它的多个副本( .cpp个文件)。之所以如此命名是因为定义必须可用于内联函数,这意味着库中的函数需要inline才能实际内联。

相关问题