繁体   English   中英

C++ 内联说明符的正确使用方法是什么?

[英]In C++ what is the correct way to use the inline specifier?

我的目标是减少我在class中定义的一些方法的 function 调用开销。 这些方法由其他方法使用,并且不打算公开访问。 我做了一些研究,但无法将我找到的信息放在一起。 在定义中而不是在声明中指定inline方法就足够了吗? 如果该方法可以公开访问,这是不是一种糟糕的技术?

文件.h

class Foo
{
    /* ... */
public:
    bool bar ( int par );
    void zar ( void );
    /* ... */
};

文件.cpp

inline bool Foo::bar ( int par )
{
    /* ... */
}

void Foo::zar ( void )
{
    /* ... */

    if ( bar(10) )
    {
        /* ... */
    }

    /* ... */
}

在此示例中使用inline说明符是一项好技术吗?

该代码是可运行的,但我想了解不可预见的后果。 这是否是正确的用法。

inline官方几乎与 function 是否内联无关。

它的官方目的是允许存在多个相同的定义而不违反 ODR(单一定义)规则。 这意味着您可以将定义放入 header 中,从多个.cpp文件(翻译单元)中包含它,并且 linker 不会抱怨多个定义,而是会选择一个 因此,您必须确保定义相同(即在单独的.cpp文件中没有两个具有相同名称的“不相关” inline函数 - 它们应该被标记为static ),否则调试调用祝你好运。

如果你想强制内联,没有标准工具,但所有编译器都支持这样做的指令,例如__attribute__((always_inline)) for g++/clang。

但是如果你想依靠编译器来使用它的判断,你可以通过确保定义在调用站点可用来帮助它。 这可以通过将定义放入标头或启用链接时优化来实现。 前者意味着将定义放在 class 内部或 class 定义之后的某处,在这种情况下将它们标记为inline 请注意,这意味着实现中的任何更改都需要重新编译所有翻译单元,其中包括 header。

在定义中而不是在声明中指定内联方法就足够了吗? 如果该方法可以公开访问,这是不是一种糟糕的技术?

不能保证但是是的,如果编译器认为内联调用是有益的,它拥有这样做所需的所有信息。 技术不好? 我会说这是完全正交的问题,调用者不应该关心“调用约定”。 仅根据 API 设计公开方法。

在此示例中使用内联说明符是一项好技术吗?

不,在单个翻译单元内内联标记 function 是没有用的。 因为它对其他单位不可见,而对原单位已经可见。 我会说,由于我的第二段,这样做甚至是危险的,如果其他人来并在file2.cpp中实现inline Foo:bar ,则 linker 很可能会默默地为所有非内联调用选择一个定义,但是内联的file.cpp中的调用将调用file::bar定义 - 正如我所说,祝你好运跟踪这些问题。

inline主要是类似于register的历史工件,这是从编译器太愚蠢到无法调用内联内容和时间(1990 年代 - 2000 年代初)时向编译器提出的建议

从 7.1.2 开始:

内联说明符向实现表明在调用点内联替换 function 主体优于通常的 function 调用机制。

如今,除了一些手动优化等特殊情况外,几乎没有你应该使用它的有效情况。 一般来说,你根本不应该使用它。

这是对程序大小执行速度的优化。 过去,您会对小函数使用inline来减少 function 调用开销。 人们有这种使用类似函数的宏的坏习惯,而inline应该可以阻止这种情况。

为了inline按预期工作,function 定义需要与调用方位于同一翻译单元(.cpp 文件及其包含的所有标头)中。 这通常意味着它需要放在 header 中。 inline公共方法不一定是坏事,尤其是简单的 setter/getter,但您不需要这样做。


编辑:

请注意, inline应与static一起使用,以确保 function 的多个定义是不可能的。 这是一个定义规则(7.1.2) 所必需的:

不需要实现在调用点执行此内联替换; 然而,即使省略了该内联替换,仍应遵守 7.1.2 定义的内联函数的其他规则。

内联 function 应在每个使用 odr 的翻译单元中定义,并且在每种情况下都应具有完全相同的定义

内联 function 应在每个使用 odr 的翻译单元中定义。

(与 C 类似,如果您在没有 static 的情况下声明inline static并且不在同一翻译单元中定义 function,则会调用未定义的行为 (6.7.4/7)。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM