Um mutable
campo pode ser alterado até mesmo em um objeto acessado por meio de um const
ponteiro ou referência, ou em um const
objeto, de forma que o compilador saiba que não deve ser armazenado na memória R / O. Uma volatile
localização é aquela que pode ser alterada por código que o compilador não conhece (por exemplo, algum driver de nível de kernel), então o compilador sabe que não deve otimizar, por exemplo, atribuição de registro desse valor sob a suposição inválida de que o valor "não pode ter alterado "desde que foi carregado pela última vez nesse registro. Informações muito diferentes fornecidas ao compilador para impedir tipos muito diferentes de otimizações inválidas.
volatile
os objetos também podem ser alterados por processos que não envolvem a CPU. Por exemplo, um registro de bytes recebidos em um periférico de comunicação pode incrementar-se no recebimento de um byte (e isso pode até disparar uma interrupção). Outro exemplo é um registro de sinalizadores de interrupções pendentes em um periférico.volatile
não significa apenas que o objeto pode mudar fora do conhecimento do compilador - também significa que as gravações no objeto não podem ser eliminadas pelo compilador, mesmo se essas gravações parecerem inúteis. Por exemplo:x = 1; x = 0;
sex
for volátil, o compilador deve emitir ambas as operações de gravação (que podem ser significativas no nível do hardware). No entanto, para um objeto não volátil, o compilador pode escolher não se preocupar em escrever o,1
pois ele nunca é usado.const
evolatile
! Você não pode alterar o objeto, mas ele pode ser alterado nas suas costas.mutable
: A palavra-chave mutável substitui qualquer instrução const envolvente. Um membro mutável de um objeto const pode ser modificado.volatile
: A palavra-chave volatile é um modificador dependente da implementação, usado ao declarar variáveis, o que impede o compilador de otimizar essas variáveis. Volátil deve ser usado com variáveis cujo valor pode mudar de maneiras inesperadas (ou seja, por meio de uma interrupção), o que pode entrar em conflito com otimizações que o compilador pode realizar.Fonte
fonte
Volatile should be used with variables whose value can change in unexpected ways
que deveríamos preferir usá-lo com aleatório?Eles definitivamente NÃO são a mesma coisa. Mutable interage com const. Se você tiver um ponteiro const, normalmente não poderá alterar os membros. Mutable fornece uma exceção a essa regra.
O volátil, por outro lado, não tem nenhuma relação com as mudanças feitas pelo programa. Isso significa que a memória pode mudar por motivos fora do controle do compilador, portanto, o compilador tem que ler ou escrever o endereço da memória todas as vezes e não pode armazenar o conteúdo em um registro.
fonte
T
, armazená-lo em umconst T*
e ler a partir dele. Se você criar esse objetovolatile
, o armazenamento de seu endereço emconst T*
falhará, mesmo que você nunca tente escrever.volatile
e as alterações / modificações / gravações na memória do código do programa são completamente ortogonais.Uma maneira rude, mas eficaz de pensar na diferença é:
fonte
volatile
bytes_received,mutable
reference_count.Uma variável marcada
mutable
permite que ela seja modificada em um método declaradoconst
.Uma variável marcada
volatile
diz ao compilador que ele deve ler / escrever a variável toda vez que seu código a disser (ou seja, ele não pode otimizar acessos de distância à variável).fonte
Eu gostaria de acrescentar que volatile também é muito útil ao lidar com aplicativos multithreading, ou seja, você tem seu thread principal (onde main () vive) e você gera um thread de trabalho que continuará girando enquanto uma variável "app_running" é verdadeira. main () controla se "app_running" é verdadeiro ou falso, então, se você não adicionar o atributo volatile à declaração de "app_running", se o compilador otimizar o acesso a "app_running" no código executado pelo thread secundário, principal ( ) pode alterar "app_running" para false, mas o thread secundário continuará em execução porque o valor foi armazenado em cache. Eu vi o mesmo comportamento usando gcc no Linux e VisualC ++. Um atributo "volatile" colocado na declaração "app_running" resolveu o problema. Então,
fonte