variable software qualifier language c pointers volatile

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 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!