Wie schränke ich in C den Gültigkeitsbereich einer globalen Variablen auf die Datei ein, in der sie deklariert ist?

7

Ich bin neu bei C. Ich habe ein Buch vor mir, das den "Dateiumfang" von C erklärt, einschließlich Beispielcode. Der Code deklariert und initialisiert jedoch nur eine Dateibereichsvariable - sie überprüft nicht den Gültigkeitsbereich der Variablen, indem sie beispielsweise versucht, auf illegale Weise darauf zuzugreifen. Damit! Im Geiste der Wissenschaft konstruierte ich ein Experiment.

Datei bar.c :

%Vor%

Datei foo.c :

%Vor%

Laut meinem Buch und Google sollte der Aufruf von printf() fehlschlagen - tut es aber nicht. foo.exe gibt die Zeichenfolge "asdf" aus und wird normal beendet. Ich würde sehr gerne Datei-Scoping verwenden. Was vermisse ich?

    
Metaphile 25.06.2009, 22:26
quelle

4 Antworten

15

Sie haben bar.c eingeschlossen, was dazu führt, dass der Präprozessor den Inhalt von bar.c vor dem Zugriff durch den Compiler buchstäblich in foo.c kopiert.

Versuchen Sie, das Include zu entfernen, aber weisen Sie Ihren Compiler an, beide Dateien zu kompilieren (z. B. gcc foo.c bar.c ) und beobachten Sie, wie Sie sich beschweren.

Edit: Ich nehme an, die primäre Verwirrung besteht zwischen dem Compiler und dem Präprozessor. Sprachregeln werden vom Compiler erzwungen. Der Präprozessor wird vor dem Compiler ausgeführt und wirkt auf die Befehle mit dem Präfix #. Der gesamte Präprozessor manipuliert reinen Text. Es analysiert nicht den Code oder versucht, die Bedeutung des Codes in irgendeiner Weise zu interpretieren. Die Anweisung "#include" ist sehr wörtlich - sie teilt dem Präprozessor mit, "den Inhalt dieser Datei hier einzufügen". Aus diesem Grund verwenden Sie normalerweise nur #include für .h (Header) -Dateien, und Sie platzieren nur Funktions-Prototypen und externe Variablendeklarationen in Header-Dateien. Andernfalls werden Sie am Ende die gleichen Funktionen kompilieren oder die gleichen Variablen mehrmals definieren, was nicht legal ist.

    
Tyler McHenry 25.06.2009, 22:27
quelle
6

Dies wird durch verwirrende Begriffe verursacht. file scope in C bezieht sich nicht auf die Beschränkung der Verknüpfung einer Kennung auf nur eine Übersetzungseinheit. Es bedeutet auch nicht, dass der Umfang auf eine physische Datei beschränkt ist. Stattdessen bedeutet file scope , dass Ihr Bezeichner global ist. Der Begriff file bezieht sich hier auf den Text, der sich aus der Verarbeitung aller #include , #define und anderer Präprozessor-Direktiven ergibt.

Im Allgemeinen ist der Anwendungsbereich nur ein Konzept, das innerhalb einer Übersetzungseinheit wirksam wird. Wenn mehrere Zusammenstellungen beteiligt sind, beginnt die Verknüpfung.

Wenn Sie Ihre Dateibereichsvariable static deklarieren, wird die Variable intern verknüpft, was bedeutet, dass sie außerhalb dieser Übersetzungseinheit nicht sichtbar ist.

Wenn Sie es nicht explizit als statisch deklarieren oder wenn Sie die Dateibereichsvariable extern deklarieren, ist es für andere Übersetzungseinheiten sichtbar: Wenn sie eine Dateibereichsvariable mit demselben Bezeichner deklarieren, wird dies der Fall sein habe diesen Bezeichner link mit derselben Variablen.

In Ihrem Fall fügt die Einbeziehung von bar.c in foo.c die Definition von fileScopeVariable in die zu kompilierende Übersetzungseinheit ein. So ist es in dieser Einheit sichtbar.

    
Johannes Schaub - litb 25.06.2009 22:43
quelle
2

Schließen Sie eine .c-Datei nicht so ein, wie Sie es dort tun. Die Sprache erlaubt das, aber C-Programmierer tun das einfach nicht, also werden Sie die Leute durcheinander bringen, wenn Sie es tun. Vermutlich einschließlich dich selbst.

"# include" bedeutet "Compiler, gehen Sie bitte zu dieser anderen Datei und heften Sie sie an den Anfang, bevor Sie mit der Kompilierung meines Codes beginnen."

Ich habe einmal einen ganzen Tag in völliger Verwirrung verloren, weil eine der vxWorks Quelldateien das getan hat. Ich bin immer noch damit beschäftigt.

    
T.E.D. 25.06.2009 23:02
quelle
0

Entfernen Sie die zweite Include-Anweisung. Wie es oben gesagt wurde ...

Vor dem Kompilieren Ihres Codes wird ein Compiler vorverarbeitet. In dieser Phase werden alle Anweisungen verarbeitet, die mit '#' beginnen, wie #include, #define und etc.

Um das Ergebnis dieser Phase zu sehen, können Sie einfach 'gcc -E' ausführen (wenn Sie gcc verwenden).

    
dmitri 25.06.2009 22:28
quelle

Tags und Links