In C gibt es mehrere Möglichkeiten zur Initialisierung von Strukturen:
struct Point { int x, y; }; struct Point p = {10, 20};
Die Felder werden in der deklarierten Reihenfolge initialisiert.
struct Point p = {.y = 20, .x = 10};
Felder können in beliebiger Reihenfolge initialisiert werden.
struct Rect { int x, y, w, h; } r = {1, 2}; // w und h == 0
struct Color { int r, g, b; }; struct Pixel { struct Point pos; struct Color col; }; struct Pixel px = {{10,20}, {255,0,0}};
Die benannte Initialisierung hilft, Fehler zu vermeiden:
struct Pixel px = {.col = {.r = 255, .g = 0, .b = 0}};
Fallstricke:
Frage: Was passiert, wenn bei der Initialisierung einer Struktur nicht alle Felder explizit angegeben werden und die Struktur als automatische lokale Variable deklariert ist?
Erwartet falsche Antwort: "Die verbleibenden Felder sind immer gleich Null."
Richtige Antwort: Automatische (lokale) Variablen, die nicht ausdrücklich initialisiert werden, bleiben mit nicht initialisierten Werten. Partielle Initialisierung initialisiert nur die ausdrücklich angegebenen Felder, die übrigen haben nicht definierte Werte (außer bei der Initialisierung über = {...}, wo die übrigen nur für statische/globale Strukturen Null sein werden).
Beispiel:
void foo() { struct Point { int x, y, z; } p = {1}; // p.x == 1, p.y und p.z == 0 (Nur durch = {1};) }
Geschichte
Im Projekt einer Grafikanwendung wurde ein Feld an den Anfang der Struktur eines Knotens hinzugefügt, ohne die allgemeine Initialisierungsmethode in verschiedenen Modulen zu überarbeiten. Infolgedessen begannen die Hälfte der Module, die Farben oder Koordinaten nicht richtig zu initialisieren, was sich in der Form von Darstellungsartefakten äußerte.
Geschichte
Im Videoprozesierer wurde die Struktur mit verschachtelten Zeigern teilweise mit = {0} initialisiert, was für globale Variablen korrekt war, jedoch nicht für lokale. Aufgrunddessen enthielten die Zeiger „Müll“, was zu ungültigen Adresszugriffen und schwer erkennbaren Abstürzen führte.
Geschichte
Bei der Hinzufügung neuer Felder zu einer großen Struktur aktualisierten die Autoren die alten Codeabschnitte mit reihenbasierter Initialisierung nicht. Wegen der Diskrepanz zwischen der Reihenfolge der Felder und der Initialisierer begannen kritische Variablen, falsche Werte zu erhalten. Nur eine Überprüfung der Struktur und die Einführung der benannten Initialisierung half, den Grund zu finden.