共用方式為


extern (C++)

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

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

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

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

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

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

extern 全域的 const 連結

當連結器在全域變數宣告之前看到 extern 時,其會在另一個編譯單位中尋找定義。 預設情況下,全域範圍內的非 const 變數宣告是外部的。 僅將 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 關鍵字套用到定義和其他檔案中的所有其他宣告:

//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 及更早版本中,編譯器一律會為 constexpr 變數提供內部連結,即使變數標記為 extern 也一樣。 在 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++"。 所有使用 extern "C" 語法的標準 include 檔案都可在 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 版開始,您可以在 /Zc:externC- 選項之後使用 /permissive- 編譯器選項來覆寫此檢查。

另請參閱

關鍵字
編譯單位和連結
C 中 extern 儲存空間類別規範
C 中識別碼的行為
C 中的連結