![](/img/trans.png)
[英]What is the correct way to declare and use a FILE * pointer in C/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.