const in der Programmiersprache C ermöglicht es, die Änderbarkeit eines Objekts zu beschränken. Bei der Arbeit mit Funktionsparametern hilft es, Daten vor versehentlicher Änderung zu schützen. Der wesentliche Unterschied in der Deklaration hängt davon ab, auf was sich der const-Modifikator bezieht und wo er sich relativ zum Zeiger befindet.
Beispiel für verschiedene Deklarationen:
void func(const int *ptr); // Zeiger auf einen konstanten int void func(int * const ptr); // konstanter Zeiger auf int void func(const int * const ptr); // konstanter Zeiger auf einen konstanten int
const int *ptr — die Daten sind unveränderlich, der Zeiger kann jedoch umgeleitet werden.int *const ptr — die Daten sind veränderlich, aber der Zeiger kann nicht umgeleitet werden.const int *const ptr — weder die Daten noch der Zeiger können innerhalb der Funktion geändert werden.Richtige Verwendung von const: ermöglicht es:
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; // Fehler: Versuch, die const-Daten zu ändern } }
Frage: Kann man die Adresse einer konstanten Variable einem normalen Zeiger zuweisen?
Erwartet falsche Antwort: "Ja, wenn man const in der Deklaration des Zeigers entfernt, erlaubt der Compiler das."
Richtige Antwort: Das "Herabstufen von const" ist nur mit expliziter Typumwandlung (casting) zulässig, aber dies führt zu undefined behavior, wenn man versucht, ein als const deklariertes Objekt zu ändern. Das ist nicht erlaubt — es verletzt die Semantik von const und führt zu Laufzeitfehlern.
Beispiel:
const int x = 5; int *ptr = (int*)&x; *ptr = 10; // UB: Änderung eines const-Objekts
Geschichte
In einem großen Projekt versuchte ein Programmierer, den Schutz von const zu umgehen, indem er einen const-Zeiger in einen normalen umwandelte und die Daten im read-only-Speichersegment modifizierte. Auf manchen Plattformen führte dies zu einem Programmabsturz (segmentation fault), auf anderen zu unauffälligen Fehlern, die schwer zu debuggen waren.
Geschichte
In einer Bibliothek zur Arbeit mit Arrays vergaß der Entwickler, die Parameter als const zu deklarieren. Infolgedessen führte ein inkorrekter Funktionsaufruf versehentlich zu einer Änderung der Ausgangsdaten, was zu einer Desynchronisierung des Zustands des Arrays und schwerwiegenden Bugs in nachfolgenden Verarbeitungsblöcken führte.
Geschichte
Bei der Erstellung einer Callback-Funktion, die in eine fremde Bibliothek übergeben werden sollte, wurde vergessen, const für den Eingabepuffer zu spezifizieren. Die Bibliothek versuchte, die Daten in einer konstanten Zeichenkette zu ändern, was auf einigen Betriebssystemen zu einem Absturz führte und lange Erklärungen über die Quelle des Problems nach sich zog.