web-dev-qa-db-fra.com

volatile contre mutable en C ++

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.

82
skydoor

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.

107
Alex Martelli

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.

Source

27
xian

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.

22
Ben Voigt

Une façon grossière mais efficace de penser la différence est la suivante:

  • Le compilateur sait quand un objet mutable change.
  • Le compilateur ne peut pas savoir quand un objet volatile change.
17
Jonathan Leffler

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).

10
Kyle Lutz

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.

4
BinCoder