Namespaces
Variants

const type qualifier

From cppreference.net

Cada tipo individual en el sistema de tipos de C tiene varias versiones calificadas de ese tipo, correspondientes a uno, dos, o los tres calificadores: const , volatile , y, para punteros a tipos objeto, restrict . Esta página describe los efectos del calificador const .

Objetos declarados con tipos calificados const pueden ser colocados en memoria de solo lectura por el compilador, y si la dirección de un objeto const nunca se toma en un programa, puede que no se almacene en absoluto.

Cualquier intento de modificar un objeto cuyo tipo está calificado como const resulta en comportamiento indefinido.

const int n = 1; // objeto de tipo calificado como const
int* p = (int*)&n;
*p = 2; // comportamiento indefinido

const las semánticas se aplican únicamente a expresiones lvalue ; cuando una expresión const lvalue se utiliza en un contexto que no requiere un lvalue, su calificador const se pierde (nótese que el calificador volatile, si está presente, no se pierde).

Las expresiones lvalue que designan objetos de tipo calificado como const y las expresiones lvalue que designan objetos de tipo struct o union con al menos un miembro de tipo calificado como const (incluyendo miembros de agregados o uniones contenidos recursivamente), no son lvalues modificables . En particular, no son asignables:

const int n = 1; // objeto de tipo const
n = 2; // error: el tipo de n está calificado como const
int x = 2; // objeto de tipo no calificado
const int* p = &x;
*p = 3; // error: el tipo del lvalue *p está calificado como const
struct {int a; const int b; } s1 = {.b=1}, s2 = {.b=2};
s1 = s2; // error: el tipo de s1 no está calificado, pero tiene un miembro const

Un miembro de una estructura o unión calificada con const adquiere la calificación del tipo al que pertenece (tanto cuando se accede usando el . operador como el -> operador).

struct s { int i; const int ci; } s;
// el tipo de s.i es int, el tipo de s.ci es const int
const struct s cs;
// los tipos de cs.i y cs.ci son ambos const int

Si un tipo de array se declara con el calificador de tipo const (mediante el uso de typedef ), el tipo de array no está calificado como const, pero su tipo de elemento sí lo está.

(until C23)

Un tipo de array y su tipo de elemento siempre se consideran idénticamente calificados como const.

(since C23)
typedef int A[2][3];
const A a = {{4, 5, 6}, {7, 8, 9}}; // array de array de const int
int* pi = a[0]; // Error: a[0] tiene tipo const int*
void *unqual_ptr = a; // OK hasta C23; error desde C23
// Notas: clang aplica la regla en C++/C23 incluso en modos C89-C17

Si un tipo de función se declara con el calificador de tipo const (mediante el uso de typedef ), el comportamiento es indefinido.

En una declaración de función, la palabra clave const puede aparecer dentro de los corchetes que se utilizan para declarar un tipo de arreglo de un parámetro de función. Califica el tipo de puntero al cual se transforma el tipo de arreglo.

Las siguientes dos declaraciones declaran la misma función:

void f(double x[const], const double y[const]);
void f(double * const x, const double * const y);
(desde C99)

Los literales compuestos calificados como const no necesariamente designan objetos distintos; pueden compartir almacenamiento con otros literales compuestos y con literales de cadena que tengan la misma representación o representaciones superpuestas.

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
(desde C99)

Un puntero a un tipo no constante puede convertirse implícitamente a un puntero a la versión calificada como constante del mismo tipo o compatible . La conversión inversa requiere una expresión de conversión (cast).

int* p = 0;
const int* cp = p; // OK: agrega calificadores (int a const int)
p = cp; // Error: descarta calificadores (const int a int)
p = (int*)cp; // OK: conversión

Tenga en cuenta que un puntero a puntero a T no es convertible a un puntero a puntero a const T ; para que dos tipos sean compatibles, sus calificaciones deben ser idénticas.

char *p = 0;
const char **cpp = &p; // Error: char* y const char* no son tipos compatibles
char * const *pcp = &p; // OK, agrega calificadores (char* a char*const)

Contenidos

Palabras clave

const

Notas

C adoptó el calificador const de C++, pero a diferencia de C++, las expresiones de tipo calificado const en C no son expresiones constantes ; no pueden usarse como etiquetas de case o para inicializar objetos de duración de almacenamiento static y thread , enumeradores , o tamaños de bit-field . Cuando se usan como tamaños de array , los arrays resultantes son VLA.

Referencias

  • Estándar C17 (ISO/IEC 9899:2018):
  • 6.7.3 Calificadores de tipo (p: 87-90)
  • Estándar C11 (ISO/IEC 9899:2011):
  • 6.7.3 Calificadores de tipo (p: 121-123)
  • Estándar C99 (ISO/IEC 9899:1999):
  • 6.7.3 Calificadores de tipo (p: 108-110)
  • Estándar C89/C90 (ISO/IEC 9899:1990):
  • 6.5.3 Calificadores de tipo

Véase también

Documentación de C++ para calificadores de tipo cv ( const y volatile )