Undefined behavior (UB, onbepaald gedrag) zijn handelingen in de code waarvan de standaard het gedrag niet definieert. In zulke gevallen kan de compiler elke beslissing nemen: het programma kan verschillend werken op verschillende platforms, compilers, of zelfs een nucleaire oorlog ontketenen (formeel!). Het gebruik van UB is de gevaarlijkste fout in C++.
Voorbeelden van UB:
int* p = new int[2]; delete[] p; int x = p[1]; // UB: toegang tot geheugen na vrijgave
Om UB te voorkomen:
Wat gebeurt er met de volgende code?
int a = 42; int b = a++ + ++a;Wat is de waarde van
b?
Antwoord:
Deze code veroorzaakt UB, omdat het de variabele a wijzigt en leest zonder volgorde van sequencing points (volgorde punten) tussen de bewerkingen. De standaard garandeert niet een bepaald resultaat, en de compiler kan elk resultaat geven of zelfs onverwachte code genereren.
Verhaal Op een project voor gegevensopslag veroorzaakte een van de ontwikkelaars een array-out-of-bounds situatie in een low-level functie. UB manifesteerde zich alleen met bepaalde gebruikersgegevens en leidde tot corruptie van de bestandsstructuur en verlies van klantgegevens.
Verhaal In een project voor microcontrollers kwamen constructies voor met het lezen van niet-geïnitialiseerde variabelen. Tests slaagden, maar een jaar na de release van het apparaat kwamen er willekeurige fouten aan het licht in de exploitatie, veroorzaakt door UB: variabelen bevatten soms rommelwaarden.
Verhaal In een groot open-source project werd een descriptor ontdekt die twee keer uit verschillende delen van de code werd vrijgegeven. Dit UB manifesteerde zich aanvankelijk zeer zelden, maar in nieuwe versies van het besturingssysteem leidde het tot frequente crashes.