J'ai une question sur la différence entre volatile et mutable. J'ai remarqué que les deux signifient que cela pourrait être changé. Quoi d'autre? S'agit-il de la même chose? Quelle est la différence? Où sont-ils applicables? Pourquoi les deux idées sont-elles proposées? Comment les utiliser de manière différente?
Merci beaucoup.
Un champ mutable
peut être modifié même dans un objet accessible via un pointeur ou une référence const
, ou dans un objet const
, afin que le compilateur sache de ne pas le ranger dans R/O mémoire. Un emplacement volatile
est un emplacement qui peut être modifié par du code que le compilateur ne connaît pas (par exemple, un pilote au niveau du noyau), de sorte que le compilateur ne sait pas l'optimiser, par exemple affectation de registre de cette valeur sous l'hypothèse non valide que la valeur "ne peut pas avoir changé" depuis qu'elle a été chargée pour la dernière fois dans ce registre. Des informations très différentes sont fournies au compilateur pour arrêter des types d'optimisations invalides très différents.
mutable
: Le mot clé mutable remplace toute instruction const englobante. Un membre modifiable 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 (c'est-à-dire par une interruption), ce qui pourrait entrer en conflit avec les optimisations que le compilateur pourrait effectuer.
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, d'autre part, est totalement indépendant des 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.
Une façon grossière mais efficace de penser la différence est la suivante:
Une variable marquée mutable
permet de la modifier dans une méthode déclarée const
.
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).
Je voudrais ajouter que volatile est également très utile lorsque vous traitez avec des applications multithreads, c'est-à-dire que vous avez votre thread principal (où réside main ()) et que vous générez un thread de travail qui continuera à tourner tandis 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 de fonctionner car la valeur a été mise en cache. J'ai vu le même comportement en utilisant gcc sous Linux et VisualC++. Un attribut "volatile" placé dans la déclaration "app_running" a résolu le problème. Donc, c'est un scénario où aucune interruption matérielle ou noyau n'est invoqué pour changer la valeur de ces variables.