const Typenqualifikator
Jeder einzelne Typ im C Typsystem hat mehrere qualifizierte Versionen dieses Typs, die einem, zweien oder allen drei der Qualifikatoren const, volatile und für Zeiger auf Objekttypen restrict entsprechen. Diese Seite beschreibt die Auswirkungen des const-Qualifikators.
Objekte, die mit const-qualifizierten Typen deklariert wurden, können vom Compiler in schreibgeschützten Speicher platziert werden, und wenn die Adresse eines const-Objekts in einem Programm nie genommen wird, muss es möglicherweise gar nicht gespeichert werden.
Jeder Versuch, ein Objekt zu ändern, dessen Typ const-qualifiziert ist, führt zu undefiniertem Verhalten.
const int n = 1; // object of const-qualified type int* p = (int*)&n; *p = 2; // undefined behavior
const-Semantik gilt nur für lvalue-Ausdrücke; wenn ein const-lvalue-Ausdruck in einem Kontext verwendet wird, der kein lvalue erfordert, geht sein const-Qualifikator verloren (beachten Sie, dass der volatile-Qualifikator, falls vorhanden, nicht verloren geht).
Die lvalue-Ausdrücke, die Objekte von const-qualifiziertem Typ bezeichnen, und die lvalue-Ausdrücke, die Objekte von Struct- oder Union-Typen mit mindestens einem Mitglied von const-qualifiziertem Typ bezeichnen (einschließlich Mitgliedern von rekursiv enthaltenen Aggregaten oder Unions), sind keine modifizierbaren lvalues. Insbesondere sind sie nicht zuweisbar
const int n = 1; // object of const type n = 2; // error: the type of n is const-qualified int x = 2; // object of unqualified type const int* p = &x; *p = 3; // error: the type of the lvalue *p is const-qualified struct {int a; const int b; } s1 = {.b=1}, s2 = {.b=2}; s1 = s2; // error: the type of s1 is unqualified, but it has a const member
Ein Mitglied eines const-qualifizierten Struktur- oder Union-Typs übernimmt die Qualifikation des Typs, zu dem es gehört (sowohl bei Zugriff über den .-Operator als auch über den ->-Operator).
struct s { int i; const int ci; } s; // the type of s.i is int, the type of s.ci is const int const struct s cs; // the types of cs.i and cs.ci are both const int
|
Wenn ein Array-Typ mit dem const-Typ-Qualifikator deklariert wird (durch Verwendung von typedef), ist der Array-Typ nicht const-qualifiziert, aber sein Elementtyp ist es. |
(bis C23) |
|
Ein Array-Typ und sein Elementtyp gelten immer als identisch const-qualifiziert. |
(seit C23) |
typedef int A[2][3]; const A a = {{4, 5, 6}, {7, 8, 9}}; // array of array of const int int* pi = a[0]; // Error: a[0] has type const int* void *unqual_ptr = a; // OK until C23; error since C23 // Notes: clang applies the rule in C++/C23 even in C89-C17 modes
Wenn ein Funktionstyp mit dem const-Typ-Qualifikator deklariert wird (durch Verwendung von typedef), ist das Verhalten undefiniert.
|
In einer Funktionsdeklaration kann das Schlüsselwort Die folgenden beiden Deklarationen deklarieren die gleiche Funktion void f(double x[const], const double y[const]); void f(double * const x, const double * const y); |
(seit C99) |
|
const-qualifizierte Compound-Literale bezeichnen nicht notwendigerweise unterschiedliche Objekte; sie können Speicher mit anderen Compound-Literalien und mit String-Literalen teilen, die zufällig die gleiche oder eine überlappende Darstellung haben. const int* p1 = (const int[]){1, 2, 3}; const int* p2 = (const int[]){2, 3, 4}; // the value of p2 may equal p1+1 _Bool b = "foobar" + 3 == (const char[]){"bar"}; // the value of b may be 1 |
(seit C99) |
Ein Zeiger auf einen nicht-const-Typ kann implizit in eine const-qualifizierte Version desselben oder eines kompatiblen Typs konvertiert werden. Die umgekehrte Konvertierung erfordert einen Cast-Ausdruck.
int* p = 0; const int* cp = p; // OK: adds qualifiers (int to const int) p = cp; // Error: discards qualifiers (const int to int) p = (int*)cp; // OK: cast
Beachten Sie, dass Zeiger auf Zeiger auf T nicht in Zeiger auf Zeiger auf const T konvertierbar sind; damit zwei Typen kompatibel sind, müssen ihre Qualifikationen identisch sein.
char *p = 0; const char **cpp = &p; // Error: char* and const char* are not compatible types char * const *pcp = &p; // OK, adds qualifiers (char* to char*const)
Inhalt |
[bearbeiten] Schlüsselwörter
[bearbeiten] Hinweise
C hat den const-Qualifikator von C++ übernommen, aber im Gegensatz zu C++ sind Ausdrücke von const-qualifiziertem Typ in C keine Konstanten Ausdrücke; sie können nicht als case-Labels oder zur Initialisierung von Objekten mit statischer und Thread-Speicherdauer, Aufzählungen oder Bit-Feld-Größen verwendet werden. Wenn sie als Array-Größen verwendet werden, sind die resultierenden Arrays VLAs.
[bearbeiten] Referenzen
- C17-Standard (ISO/IEC 9899:2018)
- 6.7.3 Typqualifikatoren (S. 87-90)
- C11-Standard (ISO/IEC 9899:2011)
- 6.7.3 Typqualifikatoren (S. 121-123)
- C99-Standard (ISO/IEC 9899:1999)
- 6.7.3 Typqualifikatoren (S. 108-110)
- C89/C90-Standard (ISO/IEC 9899:1990)
- 6.5.3 Typqualifikatoren
[bearbeiten] Siehe auch
| C++ Dokumentation für cv (
const und volatile) Typqualifikatoren |