首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么会有内联函数声明而不是内联函数调用?

为什么会有内联函数声明而不是内联函数调用?
EN

Stack Overflow用户
提问于 2018-01-24 12:59:07
回答 3查看 762关注 0票数 5

C++ (和其他各种语言)支持内联函数。如果我希望一个函数是内联的,我必须在声明中使用inline关键字。对我来说,这是非常不直观的:为什么我不能在调用函数时只使用inline?示例:

代码语言:javascript
复制
void foo(){...}
inline foo();

而不是

代码语言:javascript
复制
inline void foo(...){...}
foo();

这将允许我只在特定的地方内联该函数,而不必重复该功能。此外,每个功能都可以内联,这将使机制更加灵活。这是否有理由不支持呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-01-24 13:15:15

前言:

要内联一个函数,即内联行为,即内联扩展是一种优化,其中函数调用被重复的一组指令替换。

声明内联函数就是向链接器声明该函数将与非内联函数不同。具体来说,对于内联函数,单定义规则是不同的。内联函数允许在多个翻译单元中定义(实际上需要在使用odr功能的所有翻译单元中定义)。这与非内联函数不同,非内联函数必须在一个翻译单元中定义。inline关键字可以用于声明内联函数。

内联声明的命名类似于内联优化,虽然前者可能间接影响后者是否可行,但这两个概念是独立的。

现在,回到答案。

如果我希望一个函数是内联的,我必须在声明中使用inline关键字。

您不必使用内联关键字。如果在同一翻译单元中定义了非内联函数,则编译器可以将对非内联函数的调用进行内联扩展。即使这样,链接时间优化器也不是必需的,因为它可以看到所有的翻译单元。

示例:

代码语言:javascript
复制
// 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语句的哪个分支是对性能影响不大的“默认”分支的原因相同(这两种情况下的推理只是我的猜测):众所周知,人类在优化方面做得很差。我看不出为什么这样的语言特性不能被引入的技术原因。但我不认为这样的特性会非常有用。

票数 7
EN

Stack Overflow用户

发布于 2018-01-24 13:57:16

在C++中,inline并不意味着调用应该内联。这意味着定义可以出现在多个翻译单元中,而通常只允许一个定义。

由于头文件通常包含在C++程序的许多翻译单元中,因此头文件中的任何函数定义都将以多个翻译单元结束。因此,要使其工作,需要为这些定义使用inline关键字。但是,它仍然与内联相关,因为在这种情况下(定义在标头中),该定义在所有包含报头的调用站点上都是可用的,允许编译器内联它,因为它知道完整的定义。如果只有声明在标题中可用,则内联只能在链接期间(使用“链接时间优化”,即LTO)才能实现。

票数 3
EN

Stack Overflow用户

发布于 2018-01-24 13:12:56

简短而甜蜜的回答:“内联”不做以前的事情。现在,这意味着链接器应该忽略来自不同编译单元的多个定义,只需选择一个并与其一起运行。编译器可以随心所欲地做。大多数或所有现代编译器都忽略了“内联”。

额外的事实:在最新的和最伟大的C++中,您可以将变量声明为内联。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48423126

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档