extern (C++)

extern關鍵字可以套用至全域變數、函式或範本宣告。 它會指定符號具有 extern al 連結 。 如需連結的背景資訊,以及為何不建議使用全域變數,請參閱 翻譯單位和連結

關鍵字 extern 有四種意義,視內容而定:

  • 在非 const 全域變數宣告中, extern 指定變數或函式定義在另一個轉譯單位中。 extern必須套用在所有檔案中,但定義變數的檔案除外。

  • const在變數宣告中,它會指定變數具有 extern al 連結。 extern必須套用至所有檔案中的所有宣告。 (全域 const 變數預設有內部連結。

  • extern "C" 指定函式定義于其他地方,並使用 C 語言呼叫慣例。 extern "C"修飾詞也可以套用至區塊中的多個函式宣告。

  • 在範本宣告中, extern 指定範本已在其他地方具現化。 extern 告知編譯器它可以重複使用另一個具現化,而不是在目前位置建立新的具現化。 如需此用法 extern 的詳細資訊,請參閱 明確具現化

externconst 全域連結

當連結器在全域變數宣告之前看到 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)

externconst全域連結

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

如果標頭檔包含宣告的 externconstexpr 變數,則必須將它標示 __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- 編譯器選項覆寫此檢查。

另請參閱

關鍵字
翻譯單位和連結
externC 中的 儲存體 類別規範
C 中的識別碼行為
C 中的連結