SIOF ist sehr ein Laufzeit-Artefakt, der Compiler und Linker haben nicht viel damit zu tun. Betrachten Sie die Funktion atexit(), sie registriert Funktionen, die beim Programm-Exit aufgerufen werden. Viele CRT-Implementierungen haben etwas Ähnliches für die Programminitialisierung, nennen wir es atinit().
Initialisierung dieser globalen Variablen erfordert Ausführungscode, der Wert kann nicht vom Compiler bestimmt werden. Daher generiert der Compiler Code-Schnipsel, die den Ausdruck ausführen und den Wert zuweisen. Diese Snippets müssen ausgeführt werden, bevor main() ausgeführt wird.
Hier kommt atinit() ins Spiel. Eine gängige CRT-Implementierung führt eine Liste von Atinit-Funktionszeigern durch und führt die Initialisierungs-Snippets der Reihe nach aus. Das Problem ist die Reihenfolge, in der die Funktionen in der Liste atinit() registriert sind. Während atexit() eine gut definierte LIFO-Reihenfolge hat und implizit durch die Reihenfolge bestimmt wird, in der der Code atexit() aufruft, ist dies bei atinit-Funktionen nicht der Fall. Die Sprachspezifikation erfordert keine Bestellung. Sie können in Ihrem Code nichts tun, um eine Bestellung anzugeben. SIOF ist das Ergebnis.
Eine mögliche Implementierung ist der Compiler, der Funktionszeiger in einem separaten Abschnitt ausgibt. Der Linker führt sie zusammen und erzeugt die endgültige Liste. Wenn Ihr Compiler das tut, wird die Reihenfolge der Initialisierung durch die Reihenfolge bestimmt, in der Sie die Objektdateien verknüpfen. Sehen Sie sich die Map-Datei an, Sie sollten den Abschnitt atinit sehen, wenn Ihr Compiler dies tut. Es wird nicht atitit aufgerufen, aber eine Art von Namen mit "init" ist wahrscheinlich. Ein Blick auf den CRT-Quellcode, der main() aufruft, sollte ebenfalls einen Einblick geben.
Danke..Aber in Schritt 1, wenn wll x und y Null initialisiert werden: zur Kompilierzeit oder zur Verbindungszeit? –
@Happy Mittal: Sie können nicht sagen, und so kann der Compiler wählen. Es könnte sogar zur Programmladezeit sein. – MSalters