software - volatile char in c
¿Por qué es útil un puntero de punto a volátil, como "volatile int*p"? (2)
Este código volatile int *p = some_addr
declara un puntero a un volatile int
. El puntero en sí no es volatile
.
En el caso poco probable de que necesites el puntero para ser volátil y el int, deberías usar:
volatile int * volatile p;
No puedo pensar en una situación en la que necesitarías usar eso.
volatile
es decirle al compilador que no optimice la referencia, para que cada lectura / escritura no use el valor almacenado en el registro, pero sí un acceso real a la memoria. Puedo entender que es útil para algunas variables ordinarias, pero no entiendo qué tan volatile
afecta a un puntero.
volatile int *p = some_addr;
int a = *p; // CPU always has to load the address, then does a memory access anyway, right?
¿Cuál es la diferencia si se ha declarado como int *p = some_addr
?
Un puntero de la forma
volatile int* p;
es un puntero a un int
que el compilador considerará como volatile
. Esto significa que el compilador supondrá que es posible que la variable que apunta p
haya cambiado incluso si no hay nada en el código fuente que sugiera que esto podría ocurrir. Por ejemplo, si configuro p
para apuntar a un entero normal, cada vez que leo o escribo *p
el compilador sabe que el valor puede haber cambiado inesperadamente.
Hay un caso de uso más para una volatile int*
: si declara una int
como volatile
, entonces no debe apuntar a ella con una int*
regular. Por ejemplo, esta es una mala idea:
volatile int myVolatileInt;
int* ptr = &myVolatileInt; // Bad idea!
La razón de esto es que el compilador de C ya no recuerda que la variable apuntada por ptr
es volatile
, por lo que podría almacenar en caché el valor de *p
en un registro incorrectamente. De hecho, en C ++, el código anterior es un error. En cambio, debes escribir
volatile int myVolatileInt;
volatile int* ptr = &myVolatileInt; // Much better!
Ahora, el compilador recuerda que ptr
apunta a un volatile int
, por lo que no intentará (o no debería) intentar optimizar los accesos a través de *ptr
.
Un último detalle: el puntero que discutió es un puntero a una volatile int
. También puedes hacer esto:
int* volatile ptr;
Esto dice que el puntero en sí es volatile
, lo que significa que el compilador no debe tratar de guardar en caché el puntero en la memoria o tratar de optimizar el valor del puntero porque el puntero mismo puede ser reasignado por otra cosa (hardware, etc.) Puede combinar estos juntos si quieres obtener esta bestia:
volatile int* volatile ptr;
Esto dice que tanto el puntero como el punto podrían cambiar inesperadamente. El compilador no puede optimizar el puntero y no puede optimizar lo que se apunta.
¡Espero que esto ayude!