Calificadores de tipos
Los calificadores de tipo proporcionan una de dos propiedades a un identificador. El calificador de tipo const
declara que un objeto no es modificable. El calificador de tipo volatile
declara un elemento cuyo valor se puede modificar legítimamente por algo que esté más allá del control del programa en el que aparece, por ejemplo, un subproceso que se ejecute en paralelo.
Los calificadores de tipo, const
, restrict
y volatile
, solo pueden aparecer una vez en una declaración. Los calificadores de tipo pueden aparecer con cualquier especificador de tipo; sin embargo, no pueden aparecer después de la primera coma en una declaración de elementos múltiples. Por ejemplo, las siguientes declaraciones son válidas:
typedef volatile int VI;
const int ci;
Estas declaraciones no son válidas:
typedef int *i, volatile *vi;
float f, const cf;
Los calificadores de tipo solo son pertinentes al tener acceso a identificadores como valores L en expresiones. Vea Expresiones de valor L y de valor R para obtener información sobre valores L y expresiones.
Sintaxis
type-qualifier
:
const
restrict
volatile
const
y volatile
Las siguientes declaraciones const
y volatile
son válidas:
int const *p_ci; // Pointer to constant int
int const (*p_ci); // Pointer to constant int
int *const cp_i; // Constant pointer to int
int (*const cp_i); // Constant pointer to int
int volatile vint; // Volatile integer
Si la especificación de un tipo de matriz incluye calificadores de tipo, se califica el elemento, no de tipo de matriz. Si la especificación de tipo de la función incluye calificadores, el comportamiento es indefinido. Ni volatile
ni const
afectan al intervalo de valores ni a las propiedades aritméticas del objeto.
La palabra clave
const
se puede usar para modificar cualquier tipo fundamental o agregado, un puntero a un objeto de cualquier tipo otypedef
. Si un elemento se declara solo con el calificador de tipoconst
, se asume que su tipo es const int. Una variableconst
se puede inicializar o puede colocarse en un área de almacenamiento de solo lectura. La palabra claveconst
es útil para declarar punteros aconst
puesto que requiere que la función no cambie el puntero de ninguna manera.El compilador supone que, en cualquier punto del programa, se puede tener acceso a una variable
volatile
mediante un proceso desconocido que utilice o modifique su valor. Con independencia de las optimizaciones especificadas en la línea de comandos, el código de cada asignación de una variablevolatile
, o de cada referencia a ella, debe generarse aunque no parezca tener ningún efecto.
Si solo se usa volatile
, se supone int
. El especificador de tipo volatile
se puede utilizar para proporcionar acceso confiable a ubicaciones de memoria especiales. Use volatile
con objetos de datos a los que se pueda tener acceso o que se puedan modificar mediante controladores de la señal, ejecutando programas simultáneamente o mediante hardware especial tal como registros de control de E/S asignados a la memoria. Puede declarar una variable como volatile
mientras dure o puede convertir una única referencia para que sea volatile
.
- Un elemento puede ser a la vez
const
yvolatile
, en cuyo caso el elemento no podría modificarlo de manera legítima su propio programa, pero podría modificarlo algún proceso asincrónico.
restrict
El calificador de tipo restrict
, incluido por primera vez en C99 y disponible en los modos /std:c11
y /std:c17
, se puede aplicar a las declaraciones de puntero. Califica el puntero, no lo que señala.
restrict
es una sugerencia de optimización para el compilador de que ningún otro puntero del ámbito actual haga referencia a la misma ubicación de memoria. Es decir, solo se usa el puntero o un valor derivado de él (por ejemplo, puntero + 1) para acceder al objeto durante la vigencia del puntero. Esto ayuda al compilador a generar código más optimizado. C++ tiene un mecanismo equivalente, __restrict
.
Tenga en cuenta que restrict
es un contrato entre usted y el compilador. Si asigna un alias a un puntero marcado con restrict
, el resultado es indefinido.
Este es un ejemplo donde se usa restrict
:
void test(int* restrict first, int* restrict second, int* val)
{
*first += *val;
*second += *val;
}
int main()
{
int i = 1, j = 2, k = 3;
test(&i, &j, &k);
return 0;
}
// Marking union members restrict tells the compiler that
// only z.x or z.y will be accessed in any scope, which allows
// the compiler to optimize access to the members.
union z
{
int* restrict x;
double* restrict y;
};
Vea también
/std
(Especificar la versión estándar del lenguaje)
Declaraciones y tipos