C, das sich auf statische Initialisierer bezieht

8

Ist es in C möglich, sich gegenseitig auf statische Variableninitialisierungen zu beziehen, wie im folgenden Beispiel gezeigt?

Das Beispiel kompiliert ohne Warnung in gcc -Wall, wenn Zeile 2 hinzugefügt wird, um "B" vorzudeklarieren. Zeile 2 ist unangenehm, weil sie auch B definiert, ebenso wie Zeile 4. Das splint-lint-Programm mit -week-Prüfung warnt, dass "B" zweimal definiert ist: " Variable B neu definiert. Eine Funktion oder Variable wird neu definiert der Deklarationen sollte extern verwenden. "

Normalerweise wird eine Deklaration mit dem extern-Schlüsselwort gemacht, aber extern und statisch können nicht zusammen verwendet werden und werden nicht unter gcc kompiliert.

%Vor%

Danke

    
a b 02.10.2012, 21:26
quelle

3 Antworten

5

Trotz der seltsamen Platzierung von volatile in Relation zu static ist der von Ihnen gepostete Code absolut gültig C. Er verwendet eine C-spezifische Funktion namens vorläufige Definitionen . Diese Funktion stellt sicher, dass Sie nur ein B in Ihrem Programm haben: Beide Definitionen von B definieren dieselbe Entität. Es gibt nichts "unangenehmes" daran.

Die Warnung, die Sie von der Schiene erhalten, ist ungültig. In der C ++ - Sprache würde dies in der Tat einen Mehrfachdefinitionsfehler darstellen, aber nicht in C. Der Kommentar über extern macht im Kontext der C-Sprache keinen Sinn.

    
AnT 02.10.2012, 21:42
quelle
3

Das ist sinnlos.

BEARBEITEN:

Ja, es gibt keine Notwendigkeit in 'extern' (Danke, AndreyT und Adam Rosenfield), aber &B hat einen Typ von void** , nicht void* .

Natürlich wird void** auf void* umgesetzt, aber was ist der Sinn? Wenn Sie Aliase oder Zeiger zueinander haben wollen, dann deklarieren Sie einfach eine dritte Variable, den "Puffer", und zeigen Sie darauf in A und B.

%Vor%     
Viktor Latypov 02.10.2012 21:38
quelle
0

Es sieht vielleicht so aus, als ob Sie eine zyklische Schleife definieren, aber in Wirklichkeit sind Sie es nicht. Der Operator C & ist der -Adresse -Operator und ruft die Adresse der fraglichen Variable ab.

Wie @AndreyT darauf hingewiesen hat, hat Zeile 2 den Effekt, vorläufig zu definieren B , so dass Zeile 3 davon weiß. Sie könnten an Zeile 2 denken, wenn Sie den Speicherort für B zuweisen und dann in Zeile 4 einen Wert eingeben.

Der Code ist funktional der gleiche wie wenn Sie ihn wie folgt geschrieben hätten:

%Vor%

Also definieren Sie in Zeile 3 A , um auf die Adresse von B zu zeigen. In Zeile 4 definieren Sie B , um auf die Adresse von A zu zeigen.

Sagen wir, dass A und B die folgenden Speicheradressen haben:

%Vor%

Der Code in Zeile 3 macht folgendes:

%Vor%

Dann in Zeile 4 macht es folgendes:

%Vor%

Wenn Sie nun A und B dereferenzieren, erhalten Sie Folgendes (Achtung, Sie müssten zuerst auf einen dereferenzierbaren Zeigertyp umstellen):

%Vor%

Das ist absolut gültig, aber möglicherweise nicht das, was Sie mit Ihrem Code machen wollen.

Beachten Sie, dass zwei verschiedene Werte im Spiel sind. Zuerst ist der Wert des Zeigers. Zweitens ist die Adresse des Zeigers.

Der einzige Grund, warum Sie extern verwenden müssten, wäre die Verwendung einer Variablen, die in einer anderen Objektdatei definiert ist (zB in file1.c , die eine globale Variable verwenden soll, die in file2.c definiert ist). Das Schlüsselwort static , wenn es auf eine globale Variable angewendet wird, bedeutet, dass die Variable Datei-statisch ist oder dass sie nur in dieser Datei verwendet werden kann. Also sind die beiden offensichtlich uneins.

    
syplex 02.10.2012 23:41
quelle

Tags und Links