簡體   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