изменчивый и изменчивый в C ++ - PullRequest
82 голосов
/ 15 марта 2010

У меня есть вопрос о разнице между изменчивым и изменчивым. Я заметил, что оба эти значения означают, что это можно изменить. Что-то еще? Это одно и то же? Какая разница? Где они применимы? Почему две идеи предлагаются? Как их использовать по-другому?

Большое спасибо.

Ответы [ 6 ]

106 голосов
/ 15 марта 2010
Поле

A mutable может быть изменено даже в объекте, доступ к которому осуществляется через указатель или ссылку const, или в объекте const, поэтому компилятор знает, что не следует хранить его в памяти R / O. Расположение volatile - это местоположение, которое может быть изменено кодом, о котором не знает компилятор (например, какой-то драйвер уровня ядра), поэтому компилятор знает, что не нужно оптимизировать, например, регистровое присвоение этого значения при недопустимом допущении, что значение «возможно, не изменилось» с момента последней загрузки в этот регистр. Весьма различный вид информации, предоставляемой компилятору, чтобы остановить очень разные виды недопустимых оптимизаций.

27 голосов
/ 15 марта 2010

mutable: изменяемое ключевое слово переопределяет любой включающий оператор const. Изменяемый член const-объекта может быть изменен.

volatile: ключевое слово volatile - это зависящий от реализации модификатор, используемый при объявлении переменных, который не позволяет компилятору оптимизировать эти переменные. Volatile следует использовать с переменными, значение которых может изменяться неожиданным образом (например, через прерывание), что может конфликтовать с оптимизацией, которую может выполнить компилятор.

Источник

22 голосов
/ 15 марта 2010

Они определенно НЕ одно и то же. Мутабельный взаимодействует с const. Если у вас есть константный указатель, вы обычно не можете менять членов. Mutable предоставляет исключение из этого правила.

С другой стороны, Volatile совершенно не связано с изменениями, внесенными программой. Это означает, что память может измениться по независящим от компилятора причинам, поэтому компилятору приходится каждый раз читать или записывать адрес памяти и не может кэшировать содержимое в регистре.

17 голосов
/ 15 марта 2010

Грубый, но эффективный способ понять разницу:

  • Компилятор знает, когда изменяется изменяемый объект.
  • Компилятор не может знать, когда изменяется изменчивый объект.
10 голосов
/ 15 марта 2010

Переменная, помеченная mutable, позволяет изменять ее в методе, объявленном const.

Переменная, помеченная volatile, сообщает компилятору, что он должен читать / записывать переменную каждый раз, когда ваш код тоже сообщает об этом (т.е. он не может оптимизировать доступ к переменной).

4 голосов
/ 30 октября 2013

Я хотел бы добавить, что volatile также очень полезна при работе с многопоточными приложениями, т. Е. У вас есть основной поток (где живет main ()), и вы создаете рабочий поток, который будет вращаться, пока переменная "app_running" правда. main () контролирует, является ли «app_running» истинным или ложным, поэтому, если вы не добавите атрибут volatile в объявление «app_running», если компилятор оптимизирует доступ к «app_running» в коде, запущенном вторичным потоком, main ) может изменить "app_running" на false, но вторичный поток будет продолжать работать, потому что значение было кэшировано. Я видел такое же поведение при использовании gcc в Linux и VisualC ++. Атрибут volatile, помещенный в объявление app_running, решил проблему. Таким образом, это сценарий, в котором никакие аппаратные прерывания или ядро ​​не используются при изменении значения таких переменных.

...