2011-10-20 16 views
37

Powiel możliwe:
Static vs globalC/C++ globalny vs statycznej globalnej

Jestem mylić o różnicach między globalnych i statycznych zmiennych globalnych. Jeśli statyczne oznacza, że ​​ta zmienna jest globalna tylko dla tego samego pliku, to dlaczego w dwóch różnych plikach ta sama nazwa powoduje kolizje nazw?

Czy ktoś może to wyjaśnić?

+4

Po przesłaniu kodu ... – Nawaz

+0

Masz przykład? – glglgl

+2

Jeśli obie zmienne są zadeklarowane jako statyczne w różnych plikach, nie powinno powodować kolizji nazw.Właśnie wykonałem szybki test i działa zgodnie z oczekiwaniami. Jeśli to nie działa, opublikuj kod, w którym nie działa on zgodnie z oczekiwaniami, czego się spodziewasz i co otrzymujesz oraz jakiego kompilatora używasz. – Kevin

Odpowiedz

65

Zmienne globalne (nie static) są dostępne podczas tworzenia pliku .o dostępnego dla łącznika w celu użycia go w innych plikach. Dlatego, jeśli masz dwa pliki, takie jak to, masz nazwy kolizji na a:

AC:

#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; 
} 

ponieważ łącznik nie wie, który z globalnym a s używać.

Jednakże, gdy definiujesz statyczne globale, mówisz kompilatorowi, aby zachował zmienną tylko dla tego pliku i nie pozwól linkerowi o tym wiedzieć. Więc jeśli dodać static (w definicji a) do dwóch przykładowych kodów pisałem, nie dostaniesz kolizji nazw po prostu dlatego, że łącznik nie wie nawet, że jest a w jednym z plików:

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; 
} 

oznacza to, że każdy plik działa z własnej a nie wiedząc o pozostałych.


Na marginesie, to w porządku, że jeden z nich static a drugi nie tak długo, jak są one w różnych plikach. Jeśli dwie deklaracje znajdują się w tym samym pliku (czytaj jednostka tłumaczeniowa), jedna static i jedna extern, patrz this answer.

+0

Co z deklarowaniem jednego statycznego, a drugiego nie? – Kissaki

+1

@kissaki, jeśli te deklaracje są w różnych plikach, to jest w porządku. Plik, który ma deklarację statyczną, użyłby tej zmiennej statycznej, która jest niewidoczna dla innych plików. Wszystkie pliki, które mają niestatyczną deklarację zmiennych, użyłyby wspólnej zmiennej globalnej. – Shahbaz

+0

Jeśli te dwie deklaracje, jedna statyczna i jedna zewnętrzna, są zapisane w tym samym pliku (przeczytaj jednostkę tłumaczeniową), zobacz [ta odpowiedź] (http://stackoverflow.com/a/17043698/912144). – Shahbaz

6

Nazwa, która jest statyczna w każdym pliku, nie powinna powodować kolizji nazw. Jeśli to widzisz, opublikuj krótki (krótki) kod pokazujący go, wraz z dokładnym kompilatorem, którego używamy, abyśmy mogli właściwie zweryfikować kod i założyć, że jest on poprawny, właściwie szkaluj kompilator.

Wystarczy FWIW, preferowaną metodą w C++ jest użycie anonimowego nazw Zamiast:

namespace { 
    int not_a_static_variable; 
} 

Szczerze mówiąc, nie mogę nie można wskazać na wiele obiektywną korzyść, że choć ...

+1

'Szczerze mówiąc, nie, nie mogę wskazać na wiele obiektywnych korzyści, chociaż ...' ... Może ten temat może pomóc w pewien sposób: [Dlaczego nienazwana przestrzeń nazw jest "lepszą" alternatywą dla statycznego?] (http://stackoverflow.com/questions/4977252/why-unnamed-namespace-is-a-superior-alternative-to -static) – Nawaz

+5

C++ 11 usuwa przestarzałe obiekty statyczne, więc obecnie żadna z metod nie jest szczególnie "preferowana". –

+0

@MikeSeymour: To prawda. – Nawaz

Powiązane problemy