const type qualifier
Jeder individuelle Typ im C
Typsystem
hat mehrere
qualifizierte
Versionen dieses Typs, entsprechend einem, zwei oder allen drei der
const
,
volatile
- und, für Zeiger auf Objekttypen,
restrict
-Qualifizierer. Diese Seite beschreibt die Auswirkungen des
const
-Qualifizierers.
Objekte deklariert mit const-qualifizierten Typen können vom Compiler in schreibgeschützten Speicher platziert werden, und wenn die Adresse eines const-Objekts im Programm niemals genommen wird, muss es möglicherweise überhaupt nicht gespeichert werden.
Jeder Versuch, ein Objekt zu modifizieren, dessen Typ const-qualifiziert ist, führt zu undefiniertem Verhalten.
const int n = 1; // Objekt vom const-qualifizierten Typ int* p = (int*)&n; *p = 2; // undefiniertes Verhalten
const
Semantik gilt nur für
Lvalue
-Ausdrücke; wenn ein const-Lvalue-Ausdruck in einem Kontext verwendet wird, der keinen Lvalue erfordert, geht seine
const
-Qualifizierung verloren (beachten Sie, dass die volatile-Qualifizierung, 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-Typ mit mindestens einem Mitglied von const-qualifiziertem Typ bezeichnen (einschließlich Mitglieder von rekursiv enthaltenen Aggregaten oder Unions), sind keine modifizierbaren lvalues . Insbesondere sind sie nicht zuweisbar:
const int n = 1; // Objekt vom const-Typ n = 2; // Fehler: Der Typ von n ist const-qualifiziert int x = 2; // Objekt vom unqualifizierten Typ const int* p = &x; *p = 3; // Fehler: Der Typ des Lvalue *p ist const-qualifiziert struct {int a; const int b; } s1 = {.b=1}, s2 = {.b=2}; s1 = s2; // Fehler: Der Typ von s1 ist unqualifiziert, aber er hat ein const-Mitglied
Ein Mitglied eines const-qualifizierten Struktur- oder Union-Typs erhält die Qualifikation des Typs, zu dem es gehört (sowohl bei Zugriff mit dem
.
Operator als auch mit dem
->
Operator).
struct s { int i; const int ci; } s; // der Typ von s.i ist int, der Typ von s.ci ist const int const struct s cs; // die Typen von cs.i und cs.ci sind beide const int
|
Wenn ein Array-Typ mit dem const-Typqualifizierer deklariert wird (durch die Verwendung von typedef ), ist der Array-Typ nicht const-qualifiziert, aber sein Elementtyp ist es. |
(bis C23) |
|
Ein Array-Typ und sein Elementtyp werden immer als identisch const-qualifiziert betrachtet. |
(seit C23) |
typedef int A[2][3]; const A a = {{4, 5, 6}, {7, 8, 9}}; // Array von Array von const int int* pi = a[0]; // Fehler: a[0] hat Typ const int* void *unqual_ptr = a; // OK bis C23; Fehler seit C23 // Hinweis: clang wendet die Regel in C++/C23 auch in C89-C17 Modi an
Wenn ein Funktionstyp mit dem const-Typqualifizierer deklariert wird (durch die Verwendung von typedef ), ist das Verhalten undefiniert.
|
In einer Funktionsdeklaration kann das Schlüsselwort
Die folgenden beiden Deklarationen deklarieren dieselbe Funktion: void f(double x[const], const double y[const]); void f(double * const x, const double * const y); |
(seit C99) |
|
const-qualifizierte Compound Literals bezeichnen nicht notwendigerweise unterschiedliche Objekte; sie können Speicher mit anderen Compound Literals und mit String-Literalen teilen, die zufällig die gleiche oder ü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-konstanten Typ kann implizit in einen Zeiger auf die 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: Qualifizierer werden hinzugefügt (int zu const int) p = cp; // Fehler: Qualifizierer werden entfernt (const int zu int) p = (int*)cp; // OK: Cast-Operation
Beachten Sie, dass ein Zeiger auf einen Zeiger auf
T
nicht in einen Zeiger auf einen Zeiger auf
const T
konvertierbar ist; damit zwei Typen kompatibel sind, müssen ihre Qualifizierer identisch sein.
char *p = 0; const char **cpp = &p; // Fehler: char* und const char* sind keine kompatiblen Typen char * const *pcp = &p; // OK, fügt Qualifizierer hinzu (char* zu char*const)
Inhaltsverzeichnis |
Schlüsselwörter
Hinweise
C übernahm den const Qualifizierer von C++, aber im Gegensatz zu C++ sind Ausdrücke vom const-qualifizierten Typ in C keine konstanten Ausdrücke ; sie dürfen nicht als case -Labels verwendet werden oder zur Initialisierung von static - und thread -Speicherobjekten, Enumeratoren , oder Bitfeld -Größen dienen. Wenn sie als Array -Größen verwendet werden, sind die resultierenden Arrays VLAs.
Referenzen
- C17-Standard (ISO/IEC 9899:2018):
-
- 6.7.3 Typqualifizierer (S: 87-90)
- C11-Standard (ISO/IEC 9899:2011):
-
- 6.7.3 Type qualifiers (S.: 121-123)
- C99-Standard (ISO/IEC 9899:1999):
-
- 6.7.3 Typqualifizierer (S: 108-110)
- C89/C90 Standard (ISO/IEC 9899:1990):
-
- 6.5.3 Typqualifizierer
Siehe auch
|
C++ Dokumentation
für
cv (
const
und
volatile
) Typqualifizierer
|