const in de C-taal stelt gebruikers in staat om de wijzigbaarheid van een object te beperken. Bij het werken met functiedeclaratieparameters helpt dit om gegevens te beschermen tegen onbedoelde wijzigingen. Het belangrijkste verschil in declaraties hangt af van waar de const-modifier op betrekking heeft en waar deze zich ten opzichte van de pointer bevindt.
Voorbeeld van verschillende declaraties:
void func(const int *ptr); // pointer naar een constante int void func(int * const ptr); // constante pointer naar een int void func(const int * const ptr); // constante pointer naar een constante int
const int *ptr — de gegevens zijn onveranderlijk, maar de pointer kan opnieuw worden toegewezen.int *const ptr — de gegevens kunnen worden gewijzigd, maar de pointer kan niet opnieuw worden toegewezen.const int *const ptr — noch de gegevens, noch de pointer kunnen binnen de functie worden gewijzigd.Juiste gebruik van const: stelt in staat om:
void print_array(const int *arr, size_t n) { for (size_t i = 0; i < n; ++i) { printf("%d\n", arr[i]); // arr[i] = 10; // fout: poging om const-gegevens te wijzigen } }
Vraag: Kan het adres van een constante variabele aan een gewone pointer worden toegewezen?
Verwacht foutief antwoord: "Ja, als we const in de pointer-declaratie weghalen, staat de compiler dit toe."
Correct antwoord: "Const afbouwen" is alleen toegestaan met expliciete typecasting, maar dit leidt tot undefined behavior wanneer geprobeerd wordt een object te wijzigen dat als const is gedeclareerd. Dit is niet toegestaan, omdat het de semantiek van const schendt en leidt tot runtime-fouten.
Voorbeeld:
const int x = 5; int *ptr = (int*)&x; *ptr = 10; // UB: wijziging van const-object
Verhaal
In een groot project probeerde een programmeur de const-bescherming te omzeilen door een const-pointer naar een gewone pointer te casten en gegevens aan te passen in een read-only-geheugensegment. Op sommige platforms leidde dit tot een crash van het programma (segmentation fault), en op andere tot onopgemerkte fouten, moeilijk te debuggen.
Verhaal
In een bibliotheek voor het werken met arrays vergat een ontwikkelaar parameters als const te declareren. Hierdoor leidde een onjuiste functieaanroep per ongeluk tot wijziging van de oorspronkelijke gegevens, wat resulteerde in desynchronisatie van de status van de array en ernstige bugs in volgende verwerkingsblokken.
Verhaal
Bij het schrijven van een callback-functie, gegeven aan een externe bibliotheek, werd vergeten om const te specificeren voor de invoerbuffer. De bibliotheek probeerde de gegevens in een constante string te wijzigen, wat leidde tot crashes op sommige besturingssystemen en langdurige discussies over de oorzaak van het probleem.