In C zijn er verschillende manieren om structuren te initialiseren:
struct Point { int x, y; }; struct Point p = {10, 20};
De velden worden geïnitialiseerd in de aangegeven volgorde.
struct Point p = {.y = 20, .x = 10};
Velden kunnen in elke volgorde worden geïnitieerd.
struct Rect { int x, y, w, h; } r = {1, 2}; // w en h == 0
struct Color { int r, g, b; }; struct Pixel { struct Point pos; struct Color col; }; struct Pixel px = {{10,20}, {255,0,0}};
Benoemde initialisatie helpt om fouten te voorkomen:
struct Pixel px = {.col = {.r = 255, .g = 0, .b = 0}};
Valkuilen:
Vraag: Wat gebeurt er als niet alle velden van een structuur expliciet worden opgegeven bij de initialisatie, en de structuur is gedefinieerd als een automatische lokale variabele?
Verwacht foutief antwoord: "De resterende velden zijn altijd gelijk aan null."
Correct antwoord: Automatische (lokale) variabelen, die niet expliciet zijn geïnitialiseerd, blijven met niet-geïnitialiseerde waarden. Partiële initialisatie initialiseert alleen de expliciet opgegeven velden, de rest heeft onbepaalde waarde (tenzij geïnitialiseerd via = {...}, waar de rest alleen nullen zal zijn voor statische/globale structuren).
Voorbeeld:
void foo() { struct Point { int x, y, z; } p = {1}; // p.x == 1, p.y en p.z == 0 (Alleen via = {1};) }
Verhaal
In een grafische engine werd een veld aan het begin van de structuur van een vertex toegevoegd, zonder de algemene manier van initialisatie van objecten in verschillende modules te herzien. Als gevolg daarvan begon de helft van de modules de kleur of coördinaten verkeerd te initialiseren, wat zich uitte in visuele artefacten.
Verhaal
In een videohandler werd een structuur met geneste pointers gedeeltelijk geïnitialiseerd met = {0}, wat correct is voor globale variabelen, maar niet voor lokale. Hierdoor bevatten de pointers "rommel", wat leidde tot werken met ongeldige adressen en moeilijk te traceren crashes.
Verhaal
Bij het toevoegen van nieuwe velden aan een grote structuur hebben de auteurs de oude code-segmenten met op volgorde gebaseerde initialisatie niet bijgewerkt. Vanwege de niet-overeenkomende volgorde van velden en initialisatoren kregen kritische variabelen onjuiste waarden. Alleen een audit van de structuur en de implementatie van benoemde initialisatie hielpen de oorzaak te vinden.