Un mutable
champ peut être modifié même dans un objet accessible via un const
pointeur ou une référence, ou dans un const
objet, de sorte que le compilateur sache ne pas le mettre en mémoire R / O. Un volatile
emplacement est celui qui peut être modifié par un code que le compilateur ne connaît pas (par exemple, un pilote au niveau du noyau), donc le compilateur sait ne pas optimiser, par exemple, l'affectation de registre de cette valeur sous l'hypothèse invalide que la valeur "ne peut pas avoir changé "depuis son dernier chargement dans ce registre. Des informations très différentes sont données au compilateur pour arrêter des types très différents d'optimisations invalides.
volatile
les objets peuvent également être modifiés par des processus n'impliquant pas du tout la CPU. Par exemple, un registre octets reçus dans un périphérique de communication peut s'incrémenter à la réception d'un octet (et cela peut même déclencher une interruption). Un autre exemple est un registre d'indicateurs d'interruptions en attente dans un périphérique.volatile
cela ne signifie pas seulement que l'objet peut changer en dehors de la connaissance du compilateur - cela signifie également que les écritures sur l'objet ne peuvent pas être éliminées par le compilateur même si ces écritures semblent inutiles. Par exemple:x = 1; x = 0;
six
est volatile, le compilateur doit émettre les deux opérations d'écriture (ce qui peut être significatif au niveau matériel). Cependant, pour un objet non volatile, le compilateur pourrait choisir de ne pas se soucier d'écrire le1
car il n'est jamais utilisé.const
etvolatile
! Vous ne pouvez pas changer l'objet, mais il peut être changé derrière votre dos.mutable
: Le mot-clé mutable remplace toute instruction const englobante. Un membre mutable d'un objet const peut être modifié.volatile
: Le mot clé volatile est un modificateur dépendant de l'implémentation, utilisé lors de la déclaration de variables, qui empêche le compilateur d'optimiser ces variables. Volatile doit être utilisé avec des variables dont la valeur peut changer de manière inattendue (par exemple via une interruption), ce qui pourrait entrer en conflit avec les optimisations que le compilateur pourrait effectuer.La source
la source
Volatile should be used with variables whose value can change in unexpected ways
devrions-nous préférer l'utiliser avec aléatoire?Ce n'est certainement PAS la même chose. Mutable interagit avec const. Si vous avez un pointeur const, vous ne pouvez normalement pas changer de membre. Mutable fournit une exception à cette règle.
Volatile, en revanche, n'a aucun rapport avec les modifications apportées par le programme. Cela signifie que la mémoire peut changer pour des raisons indépendantes de la volonté du compilateur, par conséquent, le compilateur doit lire ou écrire l'adresse mémoire à chaque fois et ne peut pas mettre en cache le contenu dans un registre.
la source
T
, la stocker dans unconst T*
et la lire. Si vous créez cet objetvolatile
, le stockage de son adresseconst T*
échouera, même si vous n'essayez jamais d'écrire.volatile
et les changements / modifications / écritures en mémoire à partir du code du programme sont complètement orthogonaux.Une façon brute mais efficace de penser la différence est:
la source
volatile
bytes_received,mutable
reference_count.Une variable marquée
mutable
permet de la modifier dans une méthode déclaréeconst
.Une variable marquée
volatile
indique au compilateur qu'il doit lire / écrire la variable à chaque fois que votre code le dit aussi (c'est-à-dire qu'il ne peut pas optimiser les accès à la variable).la source
Je voudrais ajouter que volatile est également très utile lorsqu'il s'agit d'applications multithreading, c'est-à-dire que vous avez votre thread principal (où réside main ()) et que vous créez un thread de travail qui continuera à tourner tant qu'une variable "app_running" est vraie. main () contrôle si "app_running" est vrai ou faux, donc si vous n'ajoutez pas l'attribut volatile à la déclaration de "app_running", si le compilateur optimise l'accès à "app_running" dans le code exécuté par le thread secondaire, main ( ) peut changer "app_running" en false mais le thread secondaire continuera à s'exécuter car la valeur a été mise en cache. J'ai vu le même comportement en utilisant gcc sur Linux et VisualC ++. Un attribut "volatile" placé dans la déclaration "app_running" a résolu le problème. Donc,
la source