Namespaces
Variants

const type qualifier

From cppreference.net

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 const innerhalb der eckigen Klammern erscheinen, die zur Deklaration eines Array-Typs eines Funktionsparameters verwendet werden. Es qualifiziert den Zeigertyp, in den der Array-Typ transformiert wird.

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

const

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