2017-09-24 79 views
0

我有兩個文件:如何在extern變量在其他文件中聲明不同時使g ++生成警告?

a.cpp

#include <iostream> 

using namespace std; 

int a[100]; 

int main() { 
    cout << "Hello World" << endl; 
} 

b.cpp

#include <iostream> 

using namespace std; 

extern double a[50]; 

顯然有 「一」 的兩個文件有衝突的聲明。但是當我運行時

g++ a.cpp b.cpp 

編譯靜靜地成功。

有什麼辦法可以讓g ++抱怨衝突(無論是通過警告還是錯誤)?

我試過了-Wshadow和-Wshadow-all標誌。他們沒有幫助。

+1

你試過-Wshadow? –

+0

另外,加上'-Wshadow = global','local'或'compatible-local',所以你可以根據需要對其進行微調。不過,不要全局使用名稱空間。或者一般來說,理想情況下。 –

回答

2

檢測此問題的一種方法是始終將extern聲明放在標頭(.h)文件中,並將該文件包含在定義這些變量的源模塊中。

如果您創建了一個「a.h」文件,它可以包含在「a.cpp」和「b.cpp」中。接下來的編譯會導致錯誤,因爲類型在標頭中的extern double a[50];聲明和「a.cpp」中的int a[50];定義之間不匹配。

0

由於最近有足夠多的gcc版本,您可以使用-flto標誌來編譯器和鏈接器。這將調用鏈接時優化,在某些情況下,它會捕獲extern變量之間的類型不匹配。

您還可以通過確保在頭文件中聲明任何外部鏈接名稱來避免此問題。如果extern double a[50];已出現在a.cppb.cpp包含的通用標題中,您將得到a.cpp的編譯錯誤。

請注意,這不是「陰影」,這就是影子標誌沒有幫助的原因。當在名稱已經存在於外部作用域的內部作用域中重新使用相同名稱時void f() { int x; { double x; } }。但是,兩個不同的翻譯單位不是重疊範圍。

0

從g ++「觀點來看」並沒有衝突。 變量double a[50]被限制在b.cpp文件中。由於a存在於a.cpp中,因此您錯誤地認爲您正在使用相同的變量。在b.cpp的嘗試a.cpp使用它 聲明一個又一個,比方說,int b,鏈接器會抱怨:
b.cpp:

#include <iostream> 

using namespace std; 

extern char a[50]; 
extern int b; 

一個。CPP:

#include <iostream> 

using namespace std; 

int a[100]; 

int main() { 
    b=3; //using a variable unknown by this scope 
    cout << "Hello World" << endl; 
} 

編譯時,你會得到:

g++ a.cpp b.cpp 
a.cpp: In function ‘int main()’: 
a.cpp:7:5: error: ‘b’ was not declared in this scope 
    b=3; 
    ^

全局變量默認有外部鏈接,那麼該聲明之前external是相當忽視,你有什麼的聲明另一個類型爲double的變量。因此,對於鏈接器,double a[50]是一個與a.cpp中聲明的變量完全分離的變量,因爲它們處於分離的範圍內,並且沒有衝突,所以沒有抱怨。

相關問題