2010-01-29 9 views
6

Próbuję zrozumieć dokładne zachowanie specyfikatorów klas pamięci w C99, a niektóre zachowanie GCC wydaje się nie podążać za specyfikacją, chyba że źle zrozumiem specyfikację. Z 6.2.2 (2):Powiązanie w C: czy GCC stosuje specyfikację C99, czy nie rozumiem specyfikacji?

W jednej jednostki translacji, każdy zgłoszenie identyfikatora z wewnętrznym wiązaniem oznacza taki sam przedmiot lub funkcji.

Jednakże, testowane GCC (PowerPC jabłoni darwin9-gcc-4.2.1), z następującym programem:

#include <stdio.h> 
static int f() { 
    static int x = 0; 
    return x++; 
} 
static int g() { 
    static int x = 0; 
    return x++; 
} 
int main(int argc, char *argv[]) { 
    printf("g() = %i\n", g()); 
    printf("g() = %i\n", g()); 
    printf("f() = %i\n", f()); 
    printf("f() = %i\n", f()); 
    return 0; 
} 

skompilowany z -std=c99, drukuje następujące:

g() = 0 
g() = 1 
f() = 0 
f() = 1 

Jeśli dobrze rozumiem specyfikację, powinien wydrukować:

g() = 0 
g() = 1 
f() = 2 
f() = 3 

Rozumiem, dlaczego GCC odbiegałby od specyfikacji tutaj, po prostu zastanawiam się, czy istnieje głębsze wytłumaczenie tego zachowania.

Odpowiedz

9

Następny pkt, 6.2.2/3, jest ważne:

Jeżeli deklaracja plików identyfikatorem zakresu dla obiektu lub funkcji zawiera specifier przechowywania klasy statyczne, identyfikator ma wewnętrzne powiązanie.

(uwaga na podkreślony identyfikator zakresu pliku).

Twoje zmienne statyczne x nie mają zasięgu pliku, mają zasięg bloku.

+0

Innymi słowy, każde x jest lokalne dla funkcji, która je deklaruje. –

+0

Dzięki. Łatwo jest przeoczyć słowa w specyfikacji. –

+2

@Dietrich: Jest. W rzeczywistości jest to tak łatwe, że przegapiłem bardziej istotną i ważną część, która została opublikowana jako odpowiedź. –

10

W 6.2.2 (6) mówi:

następujące identyfikatory nie mają wiązania: [...] podany zakres blok identyfikator obiektu uznane bez specyfikatora extern magazynowania klasy .

Zmienne statyczne to identyfikatory zakresu bloków dla obiektów i nie są zadeklarowane jako extern. Dlatego nie mają żadnego powiązania, zwłaszcza wewnętrznego.

+2

+1; to jest bardziej istotne niż cytowany przeze mnie akapit. –

Powiązane problemy