Un mutable
campo se puede cambiar incluso en un objeto al que se accede a través de un const
puntero o referencia, o en un const
objeto, por lo que el compilador sabe que no debe guardarlo en la memoria R / O. Una volatile
ubicación es aquella que se puede cambiar mediante un código que el compilador no conoce (por ejemplo, algún controlador de nivel de kernel), por lo que el compilador sabe que no debe optimizar, por ejemplo, la asignación de registros de ese valor bajo la suposición no válida de que el valor "no puede tener cambiado "desde que se cargó por última vez en ese registro. El compilador recibe un tipo de información muy diferente para detener tipos muy diferentes de optimizaciones no válidas.
volatile
Los objetos también pueden ser cambiados por procesos que no involucran a la CPU en absoluto. Por ejemplo, un registro de bytes recibidos en un periférico de comunicaciones puede incrementarse al recibir un byte (y esto puede incluso desencadenar una interrupción). Otro ejemplo es un registro de banderas de interrupciones pendientes en un periférico.volatile
no solo significa que el objeto puede cambiar fuera del conocimiento del compilador, también significa que las escrituras en el objeto no pueden ser eliminadas por el compilador incluso si esas escrituras parecen ser inútiles. Por ejemplo:x = 1; x = 0;
six
es volátil, el compilador debe emitir ambas operaciones de escritura (que pueden ser significativas a nivel de hardware). Sin embargo, para un objeto no volátil, el compilador podría optar por no molestarse en escribir el1
ya que nunca se usa.const
comovolatile
! No puede cambiar el objeto, pero se puede cambiar a sus espaldas.mutable
: La palabra clave mutable anula cualquier instrucción const adjunta. Se puede modificar un miembro mutable de un objeto constante.volatile
: La palabra clave volátil es un modificador dependiente de la implementación, que se usa al declarar variables, lo que evita que el compilador optimice esas variables. Volátil debe usarse con variables cuyo valor puede cambiar de formas inesperadas (es decir, a través de una interrupción), lo que podría entrar en conflicto con las optimizaciones que podría realizar el compilador.Fuente
fuente
Volatile should be used with variables whose value can change in unexpected ways
que deberíamos preferir usarlo al azar?Definitivamente NO son lo mismo. Mutable interactúa con const. Si tiene un puntero constante, normalmente no podría cambiar miembros. Mutable proporciona una excepción a esa regla.
Volátil, por otro lado, no tiene ninguna relación con los cambios realizados por el programa. Significa que la memoria podría cambiar por razones que escapan al control del compilador, por lo que el compilador tiene que leer o escribir la dirección de la memoria cada vez y no puede almacenar en caché el contenido en un registro.
fuente
T
, almacenarlo en aconst T*
y leerlo. Si crea ese objetovolatile
, el almacenamiento de su direcciónconst T*
fallará, aunque nunca intente escribir.volatile
y los cambios / modificaciones / escrituras de memoria del código del programa son completamente ortogonales.Una forma tosca pero eficaz de pensar en la diferencia es:
fuente
volatile
bytes_received,mutable
reference_count.Una variable marcada
mutable
permite modificarla en un método declaradoconst
.Una variable marcada
volatile
le dice al compilador que debe leer / escribir la variable cada vez que su código también lo dice (es decir, no puede optimizar los accesos a la variable).fuente
Me gustaría agregar que volatile también es muy útil cuando se trata de aplicaciones de múltiples subprocesos, es decir, tiene su subproceso principal (donde vive main ()) y genera un subproceso de trabajo que seguirá girando mientras una variable "app_running" es verdadera. main () controla si "app_running" es verdadero o falso, por lo que si no agrega el atributo volátil a la declaración de "app_running", si el compilador optimiza el acceso a "app_running" en el código ejecutado por el subproceso secundario, main ( ) podría cambiar "app_running" a falso, pero el subproceso secundario seguirá ejecutándose porque el valor se ha almacenado en caché. He visto el mismo comportamiento al usar gcc en Linux y VisualC ++. Un atributo "volátil" colocado en la declaración "app_running" resolvió el problema. Entonces,
fuente