Initialisierung globaler und statischer Variable auf 0 ist immer unnötig?

Lesezeit: 4 Minuten

Benutzer-Avatar
Yu Hao

Der C-Standard garantiert, dass globale und statische Variablen immer vorhanden sind, wenn sie nicht initialisiert sind 0.

Hier ist meine Frage: Die nicht initialisierten globalen und statischen Variablen gehen an BSS Segment im Programm. Also die sog 0 sollte sein all-bit 0.

Für ganzzahlige Variablen gilt: all-bit 0 wird gewertet als 0. Die Fließkommavariablen, falls folgend IEEE754ist auch 0.0. Aber für Zeiger müssen Nullzeiger nicht unbedingt sein all-bit 0ebenso wie die Initialisierung eines globalen Zeigers wie folgt:

int* p = NULL;

machen keinen Unterschied zu nur:

int *p;

  • Hier einige gute Informationen: en.cppreference.com/w/cpp/language/zero_initialization

    – Vaughn Cato

    9. Juni 2013 um 18:19 Uhr

  • Dies ist kein Kommentar darüber, welchen Wert p hätte. Es ist eine Idee im Codierungsstil. Wenn Sie verwenden int *p, wird die Notwendigkeit der Initialisierung auf NULL nicht betont. Es deutet darauf hin, dass der Anfangswert a ist egalauch wenn es initialisiert ist NULL durch C. int* p = NULL; impliziert das Programm braucht diese Initialisierung zu haben. Das ist der Unterschied, den ich sehe.

    – chux – Wiedereinsetzung von Monica

    9. Juni 2013 um 18:31 Uhr

Der Standard garantiert, dass ein Zeiger mit statischer Speicherdauer und kein anderer Initialisierer als Nullzeiger initialisiert wird, unabhängig davon, um welches Bitmuster es sich handelt.

Die gleiche Grundidee gilt auch für Fließkomma- und Integer-Typen – sie werden garantiert auch mit 0 oder 0,0 initialisiert. Die Implementierung kann dies der Tatsache überlassen, dass BSS alle Bits genau dann auf 0 setzt, wenn es “weiß”, dass dies zu den richtigen Werten führt.

  • Damit nicht initialisierte Variablen nicht an BSS gehen müssen, erklärt dies mein Problem, danke.

    – Yu Hao

    9. Juni 2013 um 18:25 Uhr

  • @YuHao: Zunächst einmal bin ich mir ziemlich sicher, dass der Standard nicht wirklich angibt, wohin Variablen gehen. Solange sie irgendwo im Speicher des Zielsystems auftauchen, ist das in Ordnung. Was dieses Stück Speicher heißt, könnte “data”, “bss” oder “hhhaaa” für alles sein, was es interessiert. Es definiert jedoch, dass globale und statische Variablen auf eine bestimmte Weise initialisiert werden sollten, sodass die Implementierung “alles tun muss, was erforderlich ist” – was möglicherweise darin besteht, es einfach in BSS zu belassen und das Betriebssystem auf Null setzen zu lassen, oder es kann einen Code erfordern, um bestimmte Stellen mit etwas anderem als Null zu füllen.

    – Mats Petersson

    9. Juni 2013 um 18:31 Uhr

  • @Yu Hao: Es spielt keine Rolle, ob es “zu BSS geht” oder nicht. Der Compiler kann immer Start-Initialisierungscode generieren, der alle Auswirkungen des “Seins in BSS” außer Kraft setzt. BSS ist hier also völlig belanglos.

    – AnT steht zu Russland

    9. Juni 2013 um 18:35 Uhr


  • @MatsPetersson und AndreyT: Ich habe jetzt verstanden, dass der Compiler das richtige Programm generiert, unabhängig davon, wie das Zielsystem implementiert ist. Ich glaube, ich kenne das Computersystem besser, dank beiden aufrichtig.

    – Yu Hao

    9. Juni 2013 um 18:44 Uhr

Benutzer-Avatar
AnT steht zu Russland

Alle Variablen mit statischer Speicherdauer werden garantiert auf ihre jeweiligen Nullwerte initialisiert, was im Allgemeinen nicht bedeutet, dass sie physikalisch mit einem Nur-Bit-Null-Muster gefüllt werden müssen.

Der Grund, warum solche Variablen auf einer bestimmten Plattform in das BSS-Segment gehen könnten, ist, dass der Nullzeiger auf der Zielplattform tatsächlich durch ein Nur-Bits-Null-Muster dargestellt wird. Das heißt, die All-Bits-Zero-Initialisierung für Zeiger funktioniert auf dieser Plattform einfach korrekt, sodass der Compiler BSS als einfachste und effizienteste Methode verwendet, um das richtige Verhalten auf dieser bestimmten Plattform zu implementieren. Wäre das nicht der Fall, müsste der Compiler solche statischen Variablen anders initialisieren.

Dies würde zum Beispiel für Gleitkommawerte gelten, wenn eine Plattform eine Nicht-IEEE 754-Darstellung für solche Werte mit einem Nicht-Null-Bitmuster zum Darstellen verwendet 0.0 (C schreibt IEEE 754 nicht vor).

(Außerdem galt dies früher sogar für alle ganzzahligen Typen größer als charbis einer der TCs für den C99-Standard schließlich verlangte, dass das All-Bits-Zero-Muster eine gültige Objektdarstellung für ganzzahlige Nullen aller Typen auf allen C-Plattformen ist.)

Ein gutes Beispiel aus der Praxis kommt aus C++ (eine andere Sprache, aber in diesem Fall relevant). C++ gibt die gleiche Garantie für skalare Variablen mit statischer Speicherdauer. Mittlerweile verwenden viele gängige C++-Implementierungen 0xFFFFFFFF value zur Darstellung von Nullzeigern vom Typ Zeiger auf Datenelement. Z.B

SomeType SomeClass::*p = 0;

tatsächlich in Code übersetzt, der füllt p mit All-Bits-One-Muster. Wenn Sie also eine statische Variable dieses Typs ohne einen expliziten Initialisierer deklarieren, muss der Compiler sicherstellen, dass ihr Anfangswert ein Muster aus allen Bits und nicht aus Nullen ist. Es ist bekannt, dass einige Compiler Fehler machen, indem sie solche Variablen in BSS einfügen, sie vergessen und solche Variablen daher mit All-Bits-Null-Mustern gefüllt zurücklassen.

1335550cookie-checkInitialisierung globaler und statischer Variable auf 0 ist immer unnötig?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy