2011-10-20 38 views
37

可能重複:
Static vs globalC/C++全球VS靜態全局

我感到困惑的全局和靜態全局變量之間的差異。如果靜態意味着這個變量只對同一個文件是全局的,那麼爲什麼在兩個不同的文件中有相同的名稱會導致名稱衝突?

有人可以解釋這一點嗎?

+4

發佈代碼... – Nawaz

+0

你有例子嗎? – glglgl

+2

如果兩個變量在不同的文件中被聲明爲靜態,它不應該導致名稱衝突。我只是執行了一個快速測試,並按預期工作。如果它不適合你,請將代碼發佈到不能按預期工作的位置,期望的內容以及獲得的內容以及使用的編譯器。 – Kevin

回答

65

當您創建鏈接器可用的.o文件以在其他文件中使用時,全局變量(不是static)在那裏。因此,如果你有兩個文件就是這樣,你的名字碰撞上a

交流:

#include <stdio.h> 

int a; 

int compute(void); 

int main() 
{ 
    a = 1; 
    printf("%d %d\n", a, compute()); 
    return 0; 
} 

BC:

int a; 

int compute(void) 
{ 
    a = 0; 
    return a; 
} 

因爲鏈接不知道哪個全局的a s使用。

但是,當您定義靜態全局變量時,您告訴編譯器只爲該文件保留變量,並且不要讓鏈接器知道它。所以,如果你(在a定義)添加static我寫這兩個示例代碼,你不會得到名稱衝突只是因爲鏈接甚至不知道有處於或者文件的a

AC:

#include <stdio.h> 

static int a; 

int compute(void); 

int main() 
{ 
    a = 1; 
    printf("%d %d\n", a, compute()); 
    return 0; 
} 

BC:

static int a; 

int compute(void) 
{ 
    a = 0; 
    return a; 
} 

這意味着,每個文件的工作與自己的a在不知道其他的。


作爲一個側面說明,它的確定有他們static之一,其他沒有限制,只要它們是在不同的文件。如果兩個聲明在同一個文件中(請參閱轉換單元),一個static和一個extern,請參閱this answer

+0

如何聲明一個靜態而另一個不是? – Kissaki

+1

@kissaki,如果這些聲明在不同的文件中,那沒關係。具有靜態聲明的文件將使用對其他文件不可見的靜態變量。所有具有非靜態變量聲明的文件都將使用共享全局變量。 – Shahbaz

+0

如果這兩個聲明(一個static和一個extern)寫入同一個文件(讀取翻譯單元),請參見[本答案](http://stackoverflow.com/a/17043698/912144)。 – Shahbaz

6

在每個文件中靜態名稱應爲而不是會導致名稱衝突。如果你看到這些,請發佈(簡短)演示代碼,以及你正在使用的確切編譯器,以便我們可以正確驗證代碼並假設它是正確的,從而適當地詆譭編譯器。

只是FWIW,在C++的首選方法是使用,而不是一個匿名的命名空間:

namespace { 
    int not_a_static_variable; 
} 

實話實說,不,我不能指向很多客觀的優勢,雖然...

+1

'誠實地講,不,我不能指出很多客觀優勢,儘管...'...也許這個主題可以以某種方式提供幫助:[爲什麼無名命名空間是靜態的「優越」選擇?](http://stackoverflow.com/questions/4977252/why-unnamed-namespace-is-a-superior-alternative-to靜態的) – Nawaz

+5

C++ 11消除了對靜態對象的棄用,所以現在這兩種方法都沒有特別的「首選」。 –

+0

@MikeSeymour:也是如此。 – Nawaz