2010-01-29 3 views
6

Ich versuche, das genaue Verhalten der Speicherklasse Spezifizierer in C99 zu verstehen, und einige GCC-Verhalten scheint nicht der Spezifikation zu folgen, es sei denn, ich missverstehe die Spezifikation. Von 6.2.2 (2):Verbindung in C: Verfolgt GCC die C99-Spezifikation, oder verstehe ich die Spezifikation nicht?

Innerhalb einer Übersetzungseinheit, wobei jede Deklaration eines Bezeichners mit interner Bindung bezeichnet das gleiche Objekt oder Funktion.

Allerdings habe ich getestet GCC (powerpc-Apfel-darwin9-gcc-4.2.1) mit folgendem Programm:

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

Zusammengestellt mit -std=c99, druckt er die folgenden:

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

Wenn ich die spec richtig zu verstehen, sollte es drucken:

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

Ich verstehe, warum GCC von der Spezifikation abweichen würde, ich frage mich nur, ob es eine tiefere Erklärung für dieses Verhalten gibt.

Antwort

9

nächster Absatz 6.2.2/3 ist, ist wichtig:

Wenn die Deklaration einer Dateibereichskennung für ein Objekt oder eine Funktion der Spezifizierer Speicherklasse enthält statische, die Kennung hat interne Verknüpfung.

(beachten Sie die hervorgehobene Datei Bereichskennung).

Ihre statischen Variablen x haben keinen Dateibereich, sie haben einen Blockbereich.

+0

Mit anderen Worten, jedes x ist lokal zu der Funktion, die es deklariert. –

+0

Danke. Es ist einfach, Wörter in der Spezifikation zu verpassen. –

+2

@Dietrich: Es ist. In der Tat ist es so einfach, ich vermisste den relevanteren und wichtigeren Teil, den ich als Antwort geschrieben habe. –

10

In 6.2.2 (6) heißt es:

Die folgenden Identifikatoren keine Verknüpfung haben: [...] ein Block Umfang Kennung für ein Objekt ohne die Speicherklassen-Bezeichner extern deklarierten .

Die statischen Variablen sind Blockbereichsbezeichner für Objekte, und sie sind nicht deklariert extern. Daher haben sie keine Verknüpfung, insbesondere keine interne Verknüpfung.

+2

+1; das ist relevanter als der von mir zitierte Absatz. –

Verwandte Themen