// 1.cpp
extern const int i; // 声明
const int i = 1; // 定义
int main() { return 0; }
// 2.cpp
extern const int i = 2; // 定义并初始化
現象:1.cpp 先 extern 聲明後定義 → 鏈接報錯(重複定義)。
反過來先定義後 extern 聲明 → 鏈接成功,運行時 i=1(而非 2)。
const 變量若無 extern,具有**內部鏈接**,其他文件不可見,每個文件可有同名獨立實體。extern const int i; 聲明該變量具有**外部鏈接**,可跨文件共享,但必須有且僅有一個定義處初始化。extern const int i; 時,編譯器先向上掃描當前文件是否有**非 extern 的定義**(即 const int i = ...)。若有,綁定該定義,**不再去其他文件尋找**。若無,則去其他文件尋找 extern const int i = ... 定義。extern const int i; // 1. 向上找定義 → 無
// 2. 去外部找 → 發現 2.cpp 中 extern const int i = 2
// 3. 綁定外部定義 i=2
const int i = 1; // 4. 這是一個新的定義!與已綁定的外部符號衝突 → LNK1169 重複定義
const int i = 1; // 1. 定義並初始化,內部鏈接(因無 extern)
extern const int i; // 2. 向上找定義 → 找到步驟1 的定義
// 3. 綁定本文件定義 i=1,標記為外部可見
// 4. 不再去 2.cpp 找,2.cpp 的 extern const int i = 2 成為獨立符號(或報錯若同名外部)
結果:鏈接成功,程序使用 1.cpp 定義的 i=1。
// 1.cpp
const int i = 1;
extern const int i;
int main() { printf("%d\n", i); } // 輸出 1
// 2.cpp
extern const int i = 2; // 這裡的 i 與 1.cpp 的 i 是不同實體(若 1.cpp 未 extern)或衝突(若 1.cpp extern)
// a.h 只放 extern const int i;,僅在一個 .cpp 中放 const int i = VALUE;(不加 extern)。其他 .cpp 包含頭文件即可使用。extern const 初始化。inline const int i = 1;,編譯器自動合併,無需分離聲明定義,彻底解決跨文件 const 共享問題。extern const 跨文件鏈接規則核心在於:**編譯器優先綁定當前文件先前的非 extern 定義**。先 extern 聲明會導致綁定外部定義,後續本地定義即成重複;先本地定義則綁定本地,屏蔽外部。現代 C++ 推薦使用 inline const (C++17) 一行解決。