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!