錯誤示範
// file1.cpp
extern int sc = 0; // 錯誤:extern 不能帶初始化,這是聲明而非定義
// file2.cpp
extern int sc; // 聲明
sc = 10; // 鏈接錯誤:未定義標識符
正確做法
// file1.cpp —— 定義(僅此處分配內存)
int sc = 0;
// file2.cpp —— 聲明(告知編譯器外部存在)
extern int sc;
void func() {
sc = 10; // 正常使用
}
核心規則
- 定義:分配存儲空間,可初始化,全局作用域僅允許出現一次。
- 聲明:
extern 關鍵字,不分配內存,僅提醒編譯器符號存在於其他編譯單元,可在多文件重複出現。
extern int sc = 0; 在塊作用域外被視為定義(C++ 標準),但最佳實踐是分離:定義不加 extern,聲明必加 extern。
頭文件最佳實踐
// global.h
#ifndef GLOBAL_H
#define GLOBAL_H
extern int sc; // 聲明
#endif
// global.cpp
#include "global.h"
int sc = 0; // 定義
// main.cpp
#include "global.h"
int main() { sc = 1; }
常見坑點
- 在頭文件中直接定義(無 extern)導致多文件包含時重複定義錯誤。
- 靜態全局變量
static int sc 僅當前文件可見,無法跨文件共享。
- C++17 內聯變量
inline int sc = 0; 可直接放在頭文件定義,避免分離聲明定義。