名稱空間
變體
操作

inline 函式說明符

來自 cppreference.com
< c‎ | 語言

宣告一個行內函數

目錄

[編輯] 語法

inline 函式宣告 (C99 起)

[編輯] 解釋

inline 說明符的意圖是作為對編譯器的提示,以執行最佳化,例如函式內聯,這通常需要函式定義在呼叫點可見。編譯器可以(並且通常會)為了最佳化的目的而忽略 inline 說明符的存在與否。

如果編譯器執行函式內聯,它會將該函式的呼叫替換為其函式體,從而避免函式呼叫的開銷(將資料放在堆疊上並檢索結果),這可能會導致可執行檔案變大,因為函式的程式碼必須被多次重複。其結果類似於宏函式,不同之處在於函式中使用的識別符號和宏引用的是定義點可見的定義,而不是呼叫點。

無論是否發生內聯,行內函數的以下語義都得到保證

任何具有內部連結的函式都可以宣告為 static inline,沒有其他限制。

非靜態行內函數不能定義一個非 const 的函式區域性靜態變數,也不能引用一個檔案作用域的靜態變數。

static int x;
 
inline void f(void)
{
    static int n = 1; // error: non-const static in a non-static inline function
    int k = x; // error: non-static inline function accesses a static variable
}

如果一個非靜態函式被宣告為 inline,那麼它必須在同一個翻譯單元中定義。不使用 extern 的內聯定義在外部是不可見的,並且不阻止其他翻譯單元定義相同的函式。這使得 inline 關鍵字成為在標頭檔案中定義函式的 static 的替代方案,這些標頭檔案可能被同一程式的多個翻譯單元包含。

如果一個函式在某些翻譯單元中被宣告為 inline,它不需要在所有地方都宣告為 inline:最多一個翻譯單元可以提供一個常規的、非內聯的非靜態函式,或者一個宣告為 extern inline 的函式。這個翻譯單元被稱為提供了“外部定義”。為了避免未定義行為,如果具有外部連結的函式名在表示式中使用,則程式中必須存在一個外部定義,請參見單一定義規則

具有外部連結的行內函數的地址始終是外部定義的地址,但是當使用此地址進行函式呼叫時,未指定是呼叫“內聯定義”(如果存在於翻譯單元中)還是“外部定義”。在內聯定義中定義的靜態物件與在外部定義中定義的靜態物件是不同的。

inline const char *saddr(void) // the inline definition for use in this file
{
    static const char name[] = "saddr";
    return name;
}
 
int compare_name(void)
{
    return saddr() == saddr(); // unspecified behavior, one call could be external
}
 
extern const char *saddr(void); // an external definition is generated, too

C 程式不應依賴於呼叫的是函式的內聯版本還是外部版本,否則行為是未指定的。

[編輯] 關鍵詞

inline

[編輯] 注意

inline 關鍵字是從 C++ 中借鑑而來的,但在 C++ 中,如果一個函式被宣告為 inline,它必須在每個翻譯單元中都宣告為 inline,並且行內函數的每個定義都必須完全相同(在 C 中,定義可能不同,根據差異的不同只會導致未指定的行為)。另一方面,C++ 允許非 const 的函式區域性靜態變數,並且在 C++ 中,來自行內函數不同定義的所有函式區域性靜態變數都是相同的,但在 C 中是不同的。

[編輯] 示例

標頭檔案 "test.h"

#ifndef TEST_H_INCLUDED
#define TEST_H_INCLUDED
 
inline int sum(int a, int b)
{
    return a + b;
}
 
#endif

原始檔 "sum.c"

#include "test.h"
 
extern inline int sum(int a, int b); // provides external definition

原始檔 "test1.c"

#include <stdio.h>
#include "test.h"
 
extern int f(void);
 
int main(void)
{
    printf("%d\n", sum(1, 2) + f());
}

原始檔 "test2.c"

#include "test.h"
 
int f(void)
{
    return sum(3, 4);
}

輸出

10

[編輯] 引用

  • C23 標準 (ISO/IEC 9899:2024)
  • 6.7.4 函式說明符 (p: TBD)
  • C17 標準 (ISO/IEC 9899:2018)
  • 6.7.4 函式說明符 (p: TBD)
  • C11 標準 (ISO/IEC 9899:2011)
  • 6.7.4 函式說明符 (p: 125-127)
  • C99 標準 (ISO/IEC 9899:1999)
  • 6.7.4 函式說明符 (p: 112-113)

[編輯] 參見

C++ 文件 中關於 inline 說明符 的內容