[英]What is the correct way of using extern for global variables?
文件 a.cc
int a = 0;
文件 b.cc
#include "a.cc"
文件 main.cc
#include "b.cc"
extern int a;
int main() {
}
g++ -c a.cc
g++ -c b.cc
g++ main.cc a.o b.o
error: multiple definitions of a
我在這里做錯了什么?
您包含.cc
(或.cpp
)文件,這是錯誤的。 不要那樣做。 你需要一個 header,然后把extern int a;
:
// a.h
// include guards omitted
extern int a;
// a.cc
#include "a.h"
int a;
// b.cc
#include "a.h"
// main.cc
#include "a.h"
int main(){
// use a
}
您所做的正是 linker 所說的:您提供了“a”的多個定義。 a.cc 和 b.cc 都將變量 'a' 定義為具有外部鏈接的東西。
不要那樣做!
不要#include 源文件。 有時您確實想這樣做,但話又說回來,有時您想使用goto
。
正是編譯器告訴你的——你最終在所有三個翻譯單元中定義a
:你希望它反過來:重復包含的聲明應該是 extern,並且必須只有一個定義。 例如:
// header: stuff.h
extern int a;
void foo();
// first TU: a.cpp
#include "stuff.h"
void foo() { a += 1; }
// second TU: main.cpp
#include "stuff.h"
int a; // `a` is stored in this TU
int main() {
a = 6;
foo();
// now a == 7
}
使用包含時,想象將所有文件放在一個文件中。 這基本上就是編譯器所看到的,因為在編譯器階段之前,預處理器已經包含了所有內容。
所以你的 main.cc 開始看起來像這樣。
int a;
extern int a;
編譯器認為這沒問題,因為沒有初始化程序的 extern 只是一個聲明,因此沒有為它分配 memory。 然而,“int a”是一個定義,因此 main.o 包含為 a 分配 memory 的指令。
鏈接后,linker 會注意到 ao 和 bo 也已經定義了“a”。 “a”是因為這是它最初定義的地方,而“b”是因為 b 包括具有定義的“a”。
要解決此問題,只需在 main.cc 中刪除#include "b.cc"。 其實完全去掉b.cc,因為沒有任何意義。
如果您真的想這樣做,請使用 extern int a 為名為 ah 的“a”創建一個單獨的 header。 那么main.cc和b.cc就可以隨意包含ah而不需要重新定義a。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.