即使未明确定义为内联函数,一个非常短的函数也可以内联吗?

时间:2018-11-27 15:46:26

标签: c++ c inline-functions

我事先知道,当用C或C ++编写程序时,即使我将函数声明为“内联”,编译器也可以自由地忽略它,并决定在每次(或任何一次)调用时不对其进行扩展。 / p>

相反的事实也是如此吗?也就是说,如果编译器认为这样做会提高性能,那么编译器是否可以自动内联一个未定义为内联的非常短的函数?

另外两个子问题:此行为是否在ANSI标准中定义?在这方面,C与C ++是否有所不同,或者它们的行为相同?

4 个答案:

答案 0 :(得分:11)

inline对于编译器是否内联函数不具有约束力。这原本是要这样做的。但是从那以后,人们就认识到,函数是否值得内联取决于调用点,而函数本身取决于调用点,并且最好由编译器决定。

来自https://en.cppreference.com/w/cpp/language/inline

  

由于关键字inline的含义是非约束性的,因此编译器可以对未标记为内联的任何函数使用内联替换,并且可以随意对标记为内联的任何函数生成函数调用。这些优化选择不会更改上面列出的有关多个定义和共享静态的规则。

编辑:由于您也要求输入C,因此来自https://en.cppreference.com/w/c/language/inline

  

内联说明符的目的是作为编译器执行优化的提示,例如函数内联,该函数要求函数的定义在调用站点上可见。 出于优化目的,编译器可以(并且通常会)忽略是否存在内联说明符

答案 1 :(得分:2)

关于C和C ++之间的关系,内联说明符在每种语言中的处理方式都不同。

  • 在C ++中:先前未使用内部链接声明的内联函数(以及诸如实体和变量之类的函数,以及自C ++ 17起)将具有外部链接,并且可以从其他编译中看到单位。由于内联函数(通常)驻留在头文件中,因此这意味着同一函数将在不同的编译单元中重复定义(这违反了One definition rule,但inline使其合法) 。在构建过程结束时(链接可执行文件或共享库时),同一实体的内联定义将合并在一起。非正式地,C ++ inline的意思是:“跨多个源文件的某些功能可能有多个相同的定义,但我希望它们最终成为唯一的定义”。
  • 在C中:如果未显式指定extern,则内联函数定义在其他转换单元中不可见,不同的转换单元可能具有不同的定义,其中inline说明符用于相同的函数名称。另外,对于(inlineextern这两个函数名称,可能(最多)存在一个定义,这使该函数具有外部可见的定义(即,当一个应用地址时被选择) &运算符到函数名)。来自C的One定义规则及其与externinline的关系与C ++有所不同。

答案 2 :(得分:1)

  

如果编译器认为这样做会导致性能提高,编译器是否可以自动内联一个未定义为内联的非常短的函数?

限制:
当代码使用指向函数的指针时,则该函数需要以非内联方式存在。

限制:
当该函数在本地.c文件(而不是static以外)可见时,这可以防止简单的内联代码。

没有限制:
函数的长度不是绝对的限制,尽管是实际的限制。

我使用的嵌入式处理器通常具有内联static功能。 (给出的代码不使用指向它们的指针。)

inline关键字的用途不影响编译器内联函数的能力。

答案 3 :(得分:0)

涉及标准时,关键字inline与内联无关。

(在c ++中)规则基本上是:

  • 未声明为inline的函数只能在一个翻译联合中定义。仍然需要在使用它的每个翻译单元中将其删除。
  • 必须在每个使用了转换的翻译单元中定义一个声明为inline的函数(使用ord表示调用该函数或获取指针,...)。

因此,在标准项目设置中,遵循以下两个规则几乎总是正确的。头文件中定义的函数总是 声明为inline。在* .cpp文件中定义的函数永远不会声明为inline

这就是说,我认为编译器不能真正得出关于程序员希望通过使用或不使用关键字inline进行内联的任何结论。关键字的名称是由于命名错误而带来的不幸的遗产。