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

Do c++11-compatible compilers always ignore inline hints?

本文关键字:提示 c++11 编译器 兼容      更新时间:2023-10-16

阅读一个关于我什么时候应该为函数/方法写关键字'inline'的旧答案?说:

据说内联提示编译器你认为该函数应该内联。这在1998年可能是正确的,但十年后编译器不需要这样的提示。更不用说人类在优化代码时通常是错误的,所以大多数编译器完全忽略了"提示"。

这个答案是在2009年发布的,所以我想最终弄清楚:

  1. 现代c++11兼容编译器总是忽略用户指定的inline提示,并且只自动执行此操作吗?
  2. inline提示是否只保留以提供向后兼容性?
  3. 如果不是1.,那么这个答案是不正确的?
    不,他们只是把它解释为标准要求,但一些编译器可能只做这些(根据文档MSVC选择基于inline关键字的存在,GCC 5.1.0在决定时也会考虑inline关键字)。
  1. 不,链接时也需要inline来避免重复的符号。

inline关键字确实有意义,但不是您可能期望的意义。这并不意味着编译器必须/应该/可以内联展开函数,编译器可以决定做它认为合适的事情,不管你是否使用inline

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

例如GCC 4.7.2(它可能不是最先进的,但仍然是一个相当现代的编译器)似乎对inline的解释不超过标准的规定。如果禁用优化,它似乎不会内联函数,并且随着优化打开,它似乎会像它喜欢的那样内联。唯一的区别是编译器在不同情况下如何处理"概述"函数,使用内联它只是丢弃它,或者以一种避免在链接时重复符号的方式处理它。

  1. 现代c++11兼容的编译器总是忽略用户指定的内联提示,并且只自动这样做吗?

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

  • 内联提示是否只保留以提供向后兼容性?
  • 不,inline不是一个提示,编译器不会"忽略"inline,因为如果它这样做,你会得到多个定义错误。编译器赋予inline关键字的含义不是您似乎理解的含义。这不是暗示。

    如果编译器看不到函数定义,它就不能内联它(Link-Time Optimization改变了这一点,但是LTO的使用还不是很广泛,大多数库都没有提供支持LTO的允许链接时内联的二进制文件)。

    你应该把inline读成"这个函数定义在这个文件中是内联的"而不是"调用这个函数应该是内联的"。

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

    对于从多个翻译单元调用的函数,在头文件中定义函数并使其为inline是编译器内联它们的必要条件,但不是充分条件(因为编译器将其内联决定基于其他条件)。

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

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

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

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