extern
(C++)
extern
關鍵字可以套用至全域變數、函式或範本宣告。 它會指定符號具有 extern al 連結 。 如需連結的背景資訊,以及為何不建議使用全域變數,請參閱 翻譯單位和連結 。
關鍵字 extern
有四種意義,視內容而定:
在非
const
全域變數宣告中,extern
指定變數或函式定義在另一個轉譯單位中。extern
必須套用在所有檔案中,但定義變數的檔案除外。const
在變數宣告中,它會指定變數具有 extern al 連結。extern
必須套用至所有檔案中的所有宣告。 (全域const
變數預設有內部連結。extern "C"
指定函式定義于其他地方,並使用 C 語言呼叫慣例。extern "C"
修飾詞也可以套用至區塊中的多個函式宣告。在範本宣告中,
extern
指定範本已在其他地方具現化。extern
告知編譯器它可以重複使用另一個具現化,而不是在目前位置建立新的具現化。 如需此用法extern
的詳細資訊,請參閱 明確具現化 。
extern
非 const
全域連結
當連結器在全域變數宣告之前看到 extern
時,它會在另一個轉譯單位中尋找定義。 全域範圍的非 const
變數宣告預設為 extern al。 extern
僅適用于未提供定義的宣告。
//fileA.cpp
int i = 42; // declaration and definition
//fileB.cpp
extern int i; // declaration only. same as i in FileA
//fileC.cpp
extern int i; // declaration only. same as i in FileA
//fileD.cpp
int i = 43; // LNK2005! 'i' already has a definition.
extern int i = 43; // same error (extern is ignored on definitions)
extern
const
全域連結
const
全域變數預設具有內部連結。 如果您想要讓變數具有 extern al 連結,請將 extern
關鍵字套用至定義,並套用至其他檔案中的所有其他宣告:
//fileA.cpp
extern const int i = 42; // extern const definition
//fileB.cpp
extern const int i; // declaration only. same as i in FileA
extern constexpr
聯動
在 Visual Studio 2017 15.3 版和更早版本中,編譯器一律會提供變數內部連結,即使變數已標示 extern
為 也一 constexpr
樣。 在 Visual Studio 2017 15.5 版和更新版本中,編譯 /Zc:externConstexpr
程式參數會啟用正確的符合標準的行為。 最後,選項會變成預設值。 選項 /permissive-
未啟用 /Zc:externConstexpr
。
extern constexpr int x = 10; //error LNK2005: "int const x" already defined
如果標頭檔包含宣告的 extern
constexpr
變數,則必須將它標示 __declspec(selectany)
為正確具有其重複宣告的組合:
extern constexpr __declspec(selectany) int x = 10;
extern "C"
和 extern "C++"
函式宣告
在 C++ 中,搭配字串使用時, extern
指定另一種語言的連結慣例正用於宣告子。。 只有在先前宣告為具有 C 連結時,才能存取 C 函式和資料。 不過,您必須在另行編譯的轉譯單位中定義它們。
Microsoft C++ 支援字串 "C"
,並在 "C++"
string-literal 欄位中。 所有標準 Include 檔案都會 extern "C"
使用 語法,允許在 C++ 程式中使用執行時間程式庫函式。
範例
下列範例示範如何宣告具有 C 連結的名稱:
// Declare printf with C linkage.
extern "C" int printf(const char *fmt, ...);
// Cause everything in the specified
// header files to have C linkage.
extern "C" {
// add your #include statements here
#include <stdio.h>
}
// Declare the two functions ShowChar
// and GetChar with C linkage.
extern "C" {
char ShowChar(char ch);
char GetChar(void);
}
// Define the two functions
// ShowChar and GetChar with C linkage.
extern "C" char ShowChar(char ch) {
putchar(ch);
return ch;
}
extern "C" char GetChar(void) {
char ch;
ch = getchar();
return ch;
}
// Declare a global variable, errno, with C linkage.
extern "C" int errno;
如果函式有多個連結規格,則必須同意。 宣告函式同時具有 C 和 C++ 連結是錯誤的。 此外,如果函式的兩個宣告發生在程式中,其中一個具有連結規格,另一個沒有,則具有連結規格的宣告必須是第一個。 第一個宣告會針對任何已經有連結規格的其餘函式宣告指定連結。 例如:
extern "C" int CFunc1();
...
int CFunc1(); // Redeclaration is benign; C linkage is
// retained.
int CFunc2();
...
extern "C" int CFunc2(); // Error: not the first declaration of
// CFunc2; cannot contain linkage
// specifier.
從 Visual Studio 2019 開始,當指定時 /permissive-
,編譯器會檢查函式參數的 extern "C"
宣告是否也相符。 您無法多載宣告為 extern "C"
的函式。 從 Visual Studio 2019 16.3 版開始,您可以在 選項之後 /permissive-
使用 /Zc:externC-
編譯器選項覆寫此檢查。
另請參閱
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應