C ++(和其他各种语言)支持内联函数。如果我想要一个内联函数,我必须在声明中使用inline
关键字。对我而言,这种接缝非常不直观:为什么我在调用函数时不能只使用inline
?示例:
void foo(){...}
inline foo();
而不是
inline void foo(...){...}
foo();
这将允许我仅在特定位置内联函数而无需复制函数。此外,每个功能都可以内联,这将使机制更加灵活。有没有理由说这不支持?
答案 0 :(得分:4)
前言:
内联函数即内联的行为,即内联扩展是一种优化,其中函数调用被重复的指令集替换
声明内联函数是向链接器声明该函数的处理方式与非内联函数不同。具体而言,内联函数的单定义规则是不同的。允许在多个翻译单元中定义内联函数(并且实际上需要在函数被使用的所有翻译单元中定义)。这与非内联函数不同,非内联函数必须在一个转换单元中定义。 inline
关键字可用于声明内联函数。
虽然内联声明的命名方式与内联优化类似,虽然前者可以间接影响后者是否可行,但这两个概念是分开的。
现在,回答。
如果我想要内联函数,我必须在声明中使用
inline
关键字。
您不必使用inline关键字。如果函数在同一个转换单元中定义,则编译器可以内联对非内联函数的调用。即使这不是要求所有翻译单元的链接时优化器。
示例:
// a.cpp
void foo(){} // a non-inline function
inline void qux(){} // an inline function
void bar(){
foo(); // this call to a non-inline function can be expanded inline
// because the function is defined in the same TU
}
// b.cpp
void foo(); // the non-inline function must not be defined
// in multiple translation units
inline void qux(){} // the inline function can and must be defined
// in both translation units
void xeb(){
foo(); // this call to a non-inline function can not be expanded inline by
// the compiler because the function is not defined in the same TU
// the call can be expanded by a linker
qux(); // this call can be expanded by the compiler
// because the function is defined in the same TU
}
也就是说,链接时优化并不总是一个选项,并且函数调用确实发生在翻译单元之间,因此在某些情况下,内联定义确实是必要的,以允许内联扩展。
一个迂腐点:一个函数可以在没有inline
关键字的情况下内联声明(如果它是一个成员函数)。
为什么我在调用函数时只能使用内联?
语言中没有这样的语法。
请注意,该函数仍然必须在同一个转换单元中定义,否则编译器无法对其进行内联扩展。因此,如果您希望在多个翻译单元中进行内联扩展,则仍需要将该函数声明为内联。
我怀疑没有强制内联扩展的语法的原因可能与为什么没有办法选择if
语句的哪个分支是"默认"可能对性能产生边际影响的分支(推理只是我在两种情况下的猜测):人类在优化方面非常糟糕。我认为没有技术原因可以解释为什么不能引入这样的语言特征。但我不希望这样的功能非常有用。
答案 1 :(得分:3)
在C ++中inline
不意味着调用应该内联。这意味着允许定义在多个翻译单元中发生,而通常只允许一个定义。
由于头文件通常包含在C ++程序的许多翻译单元中,因此头文件中的任何函数定义都将以多个翻译单元结束。因此,为了实现这一目标,您需要inline
这些定义的关键字。它仍然与内联有关,因为在这种情况下(定义在标题中),定义在包含标题的所有调用站点都可用,允许编译器内联它,因为它知道完整定义。如果标题中只有声明可用,则只能在链接期间进行内联(使用'链接时优化'即LTO)。
答案 2 :(得分:1)
简短但甜蜜的回答:"内联"没有做过以往的事情。现在,这意味着链接器应该忽略来自不同编译单元的多个定义,只需选择一个并继续使用它。编译器可以随意使用。大多数或所有现代编译器都忽略"内联"。
额外事实:在最新最好的C ++中,您可以将变量声明为内联。