C++ 新增了 inline 關鍵字,可以為函數定義加上前綴,例如:
inline int max_int( int a, int b ) { return a > b ? a : b; }
給編譯器一個“提示”,程式整體上可能會從函數內聯中受益於效能。
已內聯的函數在呼叫它的每個點都會擴展其程式碼,而不是執行以下正常的函數呼叫機制:
對於非常小的函數,內聯可以提高效能。 但就像大多數其他事情一樣,也需要權衡。
內嵌關鍵字已向後移植到 C99,但要求略有不同 - 稍後會詳細介紹。
內聯函數就像(並且旨在取代)類似函數的宏。 一般來說,這是一件好事,因為內聯函數 是 函數,並且具有完整的函數語義,而不是僅由不理解 C 或 C++ 的預處理器完成的文字替換。
與 max_int() 函數等效的巨集:
#define MAX_INT(A,B) A > B ? A : B /* bad implementation */
有以下問題:
另外,一個宏:
內聯函數不存在這些問題,但可以產生相同的效能優勢。 因此,請使用內聯函數而不是類似函數的巨集。
如前所述,指定內聯只是對編譯器的一個“提示”,即程式總體上可能會從內聯函數中受益於性能。 編譯器可以隨意忽略提示。
為什麼? 因為在某些情況下,這要么不是一個好主意,要么是不可能的。 當滿足以下任一條件時,函數要麼不內聯,要麼通常不內聯:
可能還有其他原因。這一切都高度依賴函數、其參數、編譯器以及為其提供的任何選項。
如果編譯器不能或選擇不內聯函數,它會不警告您它尚未這樣做(預設)。 一些編譯器,例如 gcc,有一個 -Winline 選項,它會警告您並給出函數未內聯的原因。
指定內聯類似於指定暫存器的舊程式碼 - 它們都只是提示。
對大多數函數來說,執行函數的大部分成本都在函數體中,而不是在函數呼叫機制中。 因此,為了使函數成為內聯的良好候選者,它通常必須是:
如有疑問,請分析您的程式碼。 使用內聯不是神奇的「讓我更快」關鍵字。 此外,過度使用內聯可能會導致程式碼膨脹,從而進一步使程式的效能整體更差。
有關更多信息,請參閱內聯疾病。
通常適合內聯的函數包括:
理想的內嵌函數既提高效能又減少程式碼大小。
但是,任何內聯函數的一個警告是,如果其定義發生更改,則需要重新編譯所有使用它的程式碼。
如果內聯函數實際上是由編譯器內聯的,那麼,除了省略正常函數呼叫機制的程式碼之外,編譯器還可以:
In order for the compiler to be able to inline a function, it has to be able to “see” its definition (not just its declaration) in every .c or .cpp file it’s used in just like a macro. Hence, an inline function must be defined in a header file.
Normally, a function, like everything else, must have exactly one definition by adhering to the one definition rule (ODR). However, since the definition of an inline function is “seen” in multiple .c or .cpp files, the ODR is suspended for that function.
It is possible to have different definitions for inline functions having the same name, but this results in undefined behavior since the compiler has no way to check that every definition is the same.
To inline a function in C++, all you need do is prefix the function definition with inline — that’s it. The compiler and/or linker will automatically discard all but one definition from the final executable file for you.
However, to inline a function in C, you additionally must explicitly tell the compiler into what .o file to put the one definition in the event the compiler is either unable or unwilling to inline a function via extern inline.
For example, in exactly one .c file, you would declare a function like:
// util.c extern inline int max_int( int, int );
That tells the compiler to “put the one definition for max_int() into util.o.”
Alternatively in C, you can instead declare an inline function static also:
static inline int max_int( int a, int b ) { return a > b ? a : b; }
If you do this, then:
Inline functions, if used judiciously, can yield performance gains. Generally, only very small functions are good candidates for inlining.
Starting in C++11, inline functions can alternatively be declared constexpr, but that’s a story for another time.
以上是C 和 C++ 中的內聯函數的詳細內容。更多資訊請關注PHP中文網其他相關文章!