inline 說明符
當在函式的宣告說明符序列中使用inline說明符時,它將函式宣告為行內函數。
在類/結構體/聯合體定義中完整定義的函式,無論是成員函式還是非成員friend函式,都隱式地是行內函數,除非它附加到具名模組(C++20 起)。
|
首次宣告時被宣告為constexpr或consteval(C++20 起)的函式隱式地是行內函數。 已刪除的函式隱式地是行內函數:其(已刪除的)定義可以出現在多個翻譯單元中。 |
(C++11 起) |
|
當在具有靜態儲存期的變數(靜態類成員或名稱空間作用域變數)的宣告說明符序列中使用inline說明符時,它將變數宣告為內聯變數。 首次宣告時被宣告為constexpr的靜態資料成員隱式地是內聯變數。 |
(C++17 起) |
目錄 |
[編輯] 解釋
行內函數或內聯變數(C++17 起)具有以下屬性
- 行內函數或變數(C++17 起)的定義必須在訪問它的翻譯單元中可達(不一定在訪問點之前)。
- 具有外部連結的行內函數或變數(C++17 起)(例如,未宣告為static)具有以下附加屬性
- 程式中可以有行內函數或變數(C++17 起)的多個定義,只要每個定義出現在不同的翻譯單元中,並且(對於非靜態行內函數和變數(C++17 起))所有定義都相同。例如,行內函數或內聯變數(C++17 起)可以在標頭檔案中定義,該標頭檔案被包含在多個原始檔中。
- 它必須在每個翻譯單元中都宣告為inline。
- 它在每個翻譯單元中具有相同的地址。
在一個行內函數中,
- 所有函式定義中的函式區域性靜態物件在所有翻譯單元之間共享(它們都引用在一個翻譯單元中定義的同一個物件)。
- 所有函式定義中定義的型別在所有翻譯單元中也是相同的。
|
名稱空間作用域下的內聯 const 變數預設具有外部連結(與非內聯非 volatile const 限定變數不同)。 |
(C++17 起) |
inline關鍵字的最初意圖是作為最佳化器的指示符,表明函式內聯替換優於函式呼叫,也就是說,不是執行函式呼叫CPU指令將控制權轉移到函式體,而是執行函式體的副本,而無需生成呼叫。這避免了函式呼叫產生的開銷(傳遞引數和獲取結果),但由於函式程式碼必須重複多次,可能會導致可執行檔案更大。
由於內聯替換在標準語義中是不可觀察的,編譯器可以自由地對任何未標記為inline的函式使用內聯替換,並可以自由地對任何標記為inline的函式生成函式呼叫。這些最佳化選擇不會改變上述關於多重定義和共享靜態的規則。
|
由於C++98以來,函式關鍵字inline的含義變成了“允許多個定義”而不是“優先內聯”,因此該含義也擴充套件到變數。 |
(C++17 起) |
[編輯] 注意
如果具有外部連結的行內函數或變數(C++17 起)在不同的翻譯單元中定義不同,則程式是格式錯誤的,不需要診斷。
inline說明符不能用於塊作用域(在另一個函式內部)中的函式或變數(C++17 起)宣告。
inline說明符不能重新宣告已在翻譯單元中定義為非內聯的函式或變數(C++17 起)。
隱式生成的成員函式和任何在首次宣告時被宣告為預設的成員函式都像在類定義中定義的任何其他函式一樣是內聯的。
如果行內函數在不同的翻譯單元中宣告,則在每個翻譯單元的末尾,累積的預設引數集必須相同。
在C語言中,行內函數不必在每個翻譯單元中都宣告為inline(最多一個可以是非inline或extern inline),函式定義不必相同(但如果程式依賴於呼叫哪個函式,則行為未指定),並且函式區域性靜態變數在同一函式的不同定義之間是不同的。
|
有關內聯靜態成員的附加規則,請參閱靜態資料成員。 內聯變數消除了將C++程式碼打包為僅標頭檔案庫的主要障礙。 |
(C++17 起) |
| 功能測試宏 | 值 | 標準 | 特性 |
|---|---|---|---|
__cpp_inline_variables |
201606L |
(C++17) | 內聯變數 |
[編輯] 關鍵詞
[編輯] 示例
標頭檔案 "example.h"
#ifndef EXAMPLE_H #define EXAMPLE_H #include <atomic> // function included in multiple source files must be inline inline int sum(int a, int b) { return a + b; } // variable with external linkage included in multiple source files must be inline inline std::atomic<int> counter(0); #endif
原始檔 #1
#include "example.h" int a() { ++counter; return sum(1, 2); }
原始檔 #2
#include "example.h" int b() { ++counter; return sum(3, 4); }
[編輯] 缺陷報告
下列更改行為的缺陷報告追溯地應用於以前出版的 C++ 標準。
| 缺陷報告 | 應用於 | 釋出時的行為 | 正確的行為 |
|---|---|---|---|
| CWG 281 | C++98 | 友元函式宣告可以使用 inline 說明符 即使友元函式不是行內函數 |
禁止此類用法 |
| CWG 317 | C++98 | 即使函式在宣告之前在同一翻譯單元中有一個非內聯定義,也可以將其宣告為內聯 定義在同一翻譯單元中,也可以將其宣告為內聯 |
程式格式錯誤 在這種情況下,列舉是病態的 |
| CWG 765 | C++98 | 行內函數中定義的型別可能 在不同的翻譯單元中不同 |
此類型別在所有翻譯單元中都相同 在所有翻譯單元中都相同 |
| CWG 1823 | C++98 | 行內函數的所有定義中的字串字面量 在所有翻譯單元之間共享 |
由於一致性和實現原因,該要求被刪除 一致性和實現原因 |
| CWG 2531 | C++17 | 即使靜態資料成員在首次宣告時未宣告為constexpr,它也可以隱式內聯 它在首次宣告時未宣告為constexpr |
在這種情況下它不是隱式內聯的 在這種情況下 |
[編輯] 另請參閱
| C 文件,關於 inline
|