It ist nach dem Standard (§6.7.8 / 10) erforderlich.
Es gibt keinen technischen Grund dafür, zu haben um so zu sein, aber es war lange genug so, dass das Standard-Komitee es zu einer Anforderung machte.
Wenn man diese Anforderung weglässt, würde das Arbeiten mit statischen Variablen in vielen (meist?) Fällen etwas schwieriger werden. Insbesondere müssen Sie oft eine einmalige Initialisierung durchführen und benötigen einen zuverlässigen Startzustand, damit Sie wissen, ob eine bestimmte Variable bereits initialisiert wurde oder nicht. Zum Beispiel:
%Vor% Wenn ptr
beim Start einen beliebigen Wert enthalten könnte, müssten Sie ihn explizit auf NULL initialisieren, um zu erkennen, ob Sie Ihre einmalige Initialisierung bereits durchgeführt haben oder nicht.
Ja, weil es im Standard ist; aber wirklich, weil es kostenlos ist. Statische Variablen sehen für den generierten Objektcode genauso aus wie globale Variablen. Sie werden in .bss zugewiesen und zur Ladezeit zusammen mit all Ihren Konstanten und anderen globalen Variablen initialisiert. Da der Speicherbereich, in dem sie sich befinden, nur direkt von Ihrer ausführbaren Datei kopiert wird, wird sie mit einem Wert initialisiert, der zur Kompilierungszeit kostenlos bekannt ist. Der gewählte Wert ist 0.
Natürlich kann man nicht bestreiten, dass dies in den C-Normen steht. Erwarten Sie also, dass sich ein kompatibler Compiler so verhält.
Der technische Grund, warum es gemacht wurde könnte in der Funktionsweise des C-Startup-Codes verwurzelt sein. Es gibt normalerweise mehrere Speichersegmente, in die der Linker die Compilerausgabe einfügen muss, einschließlich eines Code- (Text-) Segments, eines Blockspeichersegments und eines initialisierten Variablensegments.
Nicht-statische Funktionsvariablen verfügen nicht über physischen Speicher, bis der Bereich der Funktion zur Laufzeit erstellt wird, so dass der Linker nichts damit zu tun hat.
Natürlich geht Programmcode in das Code- (oder Text-) Segment, aber auch die Werte , die zum Initialisieren von globalen und statischen Variablen verwendet werden. Initialisierte Variablen selbst (d. H. Ihre Adressen) gehen in das initialisierte Speichersegment. Nicht initialisierte globale und statische Variablen gehen in das Blockspeichersegment (bss).
Wenn das Programm zur Ausführungszeit geladen wird, erstellt ein kleines Stück Code die C-Laufzeitumgebung. In ROM-basierten Systemen wird der Wert der initialisierten Variablen aus dem Code- (Text-) Segment in ihre jeweilige tatsächliche Adresse im RAM kopiert. Auf RAM (d.h. Platten) basierende Systeme können die Anfangswerte direkt in die endgültigen RAM-Adressen laden.
Die CRT (C runtime) setzt auch das bss, das alle globalen und statischen Variablen ohne Initialisierer enthält, auf Null. Dies wurde wahrscheinlich als Vorsichtsmaßnahme gegen nicht initialisierte Daten durchgeführt. Es ist eine relativ einfache Blockfülloperation, da alle globalen und statischen Variablen in ein Adresssegment zusammengepfercht sind.
Natürlich erfordern floats und double may eine spezielle Behandlung, weil ihr 0.0-Wert möglicherweise nicht alle Null-Bits sind, wenn das Floating-Format nicht IEEE 754 ist.
Beachten Sie, dass nicht durch den Laufzeit-Startup-Code initialisiert werden kann, da Autovivariablen zur Programmladezeit nicht existieren.
Meistens weil die statischen Variablen durch den Linker in einem Block gruppiert sind, so ist es wirklich einfach, den ganzen Block beim Start auf 0 zu setzen. Ich glaube nicht, dass das von den C oder C ++ Standards verlangt wird.
Es gibt eine Diskussion über dieses hier :
Zunächst müssen in ISO C (ANSI C) alle statischen und globalen Variablen vor dem Programmstart initialisiert werden. Wenn der Programmierer das nicht explizit getan hat, muss der Compiler sie auf Null setzen. Wenn der Compiler dies nicht tut, folgt er nicht ISO C. Genau wie die Variablen initialisiert werden, ist jedoch vom Standard nicht spezifiziert.
Angenommen, Sie haben einen C-Compiler geschrieben. Sie erwarten, dass einige statische Variablen anfängliche Werte haben, daher müssen diese Werte irgendwo in der ausführbaren Datei erscheinen, die der Compiler erstellen wird. Wenn jetzt das Ausgabeprogramm ausgeführt wird, wird die gesamte ausführbare Datei in den Speicher geladen. Ein Teil der Initialisierung des Programms besteht darin, die statischen Variablen zu erzeugen, so dass alle diese Anfangswerte in ihre endgültigen statischen Variablenziele kopiert werden müssen.
Oder sie? Sobald das Programm startet, werden die Anfangswerte der Variablen nicht mehr benötigt. Können die Variablen selbst nicht innerhalb des ausführbaren Codes selbst liegen? Dann müssen die Werte nicht kopiert werden. Die statischen Variablen könnten in einem Block existieren, der sich in der ursprünglichen ausführbaren Datei befand, und für sie muss überhaupt keine Initialisierung durchgeführt werden.
Wenn das der Fall ist, warum möchten Sie dann einen speziellen Fall für nicht initialisierte statische Variablen machen? Warum nicht einfach einen Haufen Nullen in die ausführbare Datei einfügen, um die nicht initialisierten statischen Variablen darzustellen? Das würde für etwas Zeit und viel weniger Komplexität etwas Platz tauschen.
Ich weiß nicht, ob sich ein C-Compiler tatsächlich auf diese Weise verhält, aber ich vermute, dass die Möglichkeit, die Dinge auf diese Weise zu tun, das Design der Sprache beeinflusst haben könnte.
Tags und Links c