software - volatile char in c
¿Cuál es el propósito de la palabra clave "volátil" que aparece dentro de un subíndice de matriz? (2)
Mientras navegaba por cppreference, vi una matriz de tipo extraño en parámetros de función como este:
void f(double x[volatile], const double y[volatile]);
Entonces, ¿cuál es el propósito de la palabra clave volatile
aparece dentro de un subíndice de matriz? ¿Qué hace?
En general, esta característica de C (y solo de C) permite especificar cualquier calificador de tipo dentro de los corchetes de matriz; La cotización estándar exacta es:
Una declaración de un parámetro como '''' matriz de tipo '''' se ajustará a '''' puntero calificado a tipo '''', donde los calificadores de tipo (si los hay) son los especificados dentro de
[
y]
de la derivación de tipo de matriz . Si la palabra clavestatic
también aparece dentro de[
y]
de la derivación del tipo de matriz, entonces para cada llamada a la función, el valor del argumento real correspondiente proporcionará acceso al primer elemento de una matriz con al menos la cantidad de elementos especificados por la expresión de tamaño.
(C99, §6.7.5.3, ¶7, énfasis agregado)
Esto significa que esto no solo se limita a la volatile
, sino que también se permite la const
y la restrict
(consulte Calificadores de tipo , §6.7.3 ¶1).
El objetivo de este truco es esencialmente permitirle agregar un calificador de tipo al parámetro ( no al elemento de la matriz) y aún conservar la sintaxis de la matriz para la declaración; sin esta sintaxis, se ve forzado a volver a escribirlo como un puntero (que es de lo que se reduce de todos modos, excepto en el caso static
, en el que AFAIK no tiene una sintaxis de puntero equivalente).
Sospecho que la idea es sobre todo hacer que la sintaxis sea un poco menos incómoda para arreglos multidimensionales; citando §6.7.5.3 ¶21:
void f(double (* restrict a)[5]);
void f(double a[restrict][5]);
void f(double a[restrict 3][5]);
son todos equivalentes, pero 2 y 3 pueden transmitir un poco mejor que esto no es solo un puntero, sino una matriz, y aún así dejar un lugar para colocar el calificador de restrict
.
Además, como se dijo anteriormente, parece que no hay manera de tener algo como
void f(double a[restrict static 3][5]);
(que "también especifica que el argumento correspondiente a a
en cualquier llamada a f
debe ser un puntero no nulo a la primera de al menos tres matrices de 5 dobles", ibidem ) con la sintaxis de puntero "regular".
Aún así, me mantendría alejado de esta sintaxis; es extremadamente oscuro, rara vez se usa (no creo que haya necesitado nunca agregar un calificador de tipo a un parámetro de matriz; nuevamente, el parámetro en sí, no el tipo de elemento; restrict
es el único caso de uso que puede tener sentido), y no portátil a C ++ (que generalmente es relevante si está escribiendo una biblioteca).
La palabra clave volatile
se utiliza para declarar un tipo de matriz de un parámetro de función.
Aquí, double x[volatile]
es equivalente a double * volatile x
.
El cppreference dice:
En una declaración de función, la palabra clave
volatile
puede aparecer dentro de los corchetes que se utilizan para declarar un tipo de matriz de un parámetro de función. Califica el tipo de puntero al que se transforma el tipo de matriz. Las dos declaraciones siguientes declaran la misma función:
void f(double x[volatile], const double y[volatile]); void f(double * volatile x, const double * volatile y);
Esta sintaxis solo es válida en lenguaje C en parámetros de función.