Mientras leía me encontré con este tipo de declaración y la siguiente línea:
const volatile char *p=(const volatile char *) 0x30;El valor de p cambia solo por condiciones externas
No entiendo cuáles son las condiciones externas. Y también ¿cuál es el uso práctico de este tipo de declaración ?
La const dice que el flujo de su programa no va a modificar lo que señala p . Cualquier intento de modificar el valor después de eliminar la referencia del puntero generará un error en tiempo de compilación:
*p = 'A'; // will not compile Tenga en cuenta que este no es un contrato particularmente fuerte; el valor en la ubicación 0x30 aún se puede cambiar a través de un puntero no constante de alias, que no sea p :
volatile char *q = 0x30; *q = 'A'; // will compile Otra forma de romper este contrato es desechando la const de p :
*(volatile char *) p = 'A'; // will compile El volatile , sin embargo, no excluye ninguna modificación que pueda ser causada por otro hilo, el núcleo, un controlador de señal asíncrono o un dispositivo externo que tenga acceso al mismo espacio de memoria. De esta forma, el compilador no puede asumir erróneamente que el valor señalado por p no cambia y lo cargará desde la memoria cada vez que se haga referencia a él:
/* The character at 0x30 will be read on every iteration, even if the compiler has proven that the program itself doesn't modify the value at that address. */ while (*p) { ... }Si el compilador optimizara erróneamente tal construcción, podría emitir instrucciones que cargan el valor solo una vez desde la memoria y luego lo mantienen en un registro. El registro es esencialmente una copia independiente y cualquier cambio en la ubicación original no se reflejará allí y, por supuesto, esto puede causar algunos errores muy desagradables.
Considere un registro de hardware de solo lectura, de su tarjeta de red, por ejemplo.
Puede cambiar fuera del control del programa, por lo que el compilador no puede almacenar en caché su valor en un registro ni optimizarlo. Por lo tanto, volatile .
Y es de solo lectura, por lo que no debe escribir en él. Así, const .
Primero, permítanme citar el ejemplo del estándar C11 , capítulo §6.7.3, Calificadores de tipo
Un objeto declarado
extern const volatile int real_time_clock;puede ser modificable por hardware, pero no puede ser asignado, incrementado o decrementado.
También, nota al pie relacionada (134),
Se puede utilizar una declaración volátil para describir un objeto correspondiente a un puerto de entrada/salida mapeado en memoria o un objeto al que accede una función de interrupción asíncrona. Las acciones sobre los objetos así declarados no se "optimizarán" mediante una implementación ni se reordenarán excepto según lo permitido por las reglas para evaluar expresiones.
Eso significa que el hardware puede modificar el valor de la variable (a través del mapeo de memoria), pero no puede modificarse "programáticamente".
Entonces, la ventaja es doble aquí,