Как видно из названия — есть ли случаи, когда volatile
полезен в контексте однопоточного программирования? Я знаю, что он используется, чтобы убедиться, что значение переменной всегда фактически проверяется в памяти, поэтому есть ли случаи, когда это значение может измениться (в приложении ST) таким образом, что приложение / компилятор не заметит?
Я оставляю этот вопрос независимым от языка, поскольку не знаю каких-либо различий между ними, которые могли бы повлиять на ответ на этот вопрос. Но если есть, пожалуйста, дайте мне знать.
Редактировать: Как мне было указано, вопрос не зависит от языка. Тогда я делаю его специфичным для C ++ (я читал, что есть различия и в версиях C ++, но я надеюсь, что они недостаточно велики, чтобы сделать этот вопрос слишком широким).
Это ответ для C и C ++
Да! Когда переменная отображается в аппаратный регистр (например, устройство ввода-вывода). Аппаратное обеспечение изменяет регистр независимо от приложения.
Пример:
extern volatile uint32_t MY_DEVICE_START; // write-only register
extern volatile const uint32_t MY_DEVICE_STATUS; // read-only register
extern volatile uint32_t MY_DEVICE_DATA; // read-write register
...
MY_DEVICE_DATA = 42; // send input to the device
MY_DEVICE_START = 1; // start the device
while (MY_DEVICE_STATUS == 0) {} // busy-wait for the device to finish
int result = MY_DEVICE_DATA; // read output from the device
...
По крайней мере, в C / C ++ это главная причина этого. Летучий даже не рекомендуется для многопоточного использования.
Другие ответы на что volatile
есть, но я хочу привести реальный пример, который я использую для когда volatile
может быть полезным (без попыток чтения / записи в специальные области памяти оборудования).
Один пример, где volatile
может быть полезен в программах на C или C ++ для отладки. Рассмотрим следующий пример:
void do_thing(const std::vector<int>& v) {
if (v.empty()) {
do_thing_1();
} else {
do_thing_2();
}
}
Если я хочу проверить вышеупомянутую функцию и заставить ее принять ветвь true или false во время отладки, я могу вставить volatile
Переменная в условие if:
void do_thing(const std::vector<int>& v) {
volatile bool condition = v.empty();
if (condition) {
do_thing_1();
} else {
do_thing_2();
}
}
я сделала это volatile
поэтому оптимизатор не полностью оптимизирует переменную. Это позволяет легко установить точку останова на if
и тогда я могу изменить condition
(без необходимости изменять v
).
Я также могу сделать condition
static
переменная, поэтому мне не нужно продолжать нажимать точку останова: я могу нажать ее один раз, установить, и тогда она «запомнит» мой выбор.
Это, конечно, хак, но я нашел, что это очень полезно в некоторых конкретных ситуациях.
Однопоточная программа также может иметь обработку сигналов или даже на не многопоточных платформах может использоваться аппаратная обработка прерываний, поэтому нелокальные переменные, измененные в функции-обработчике, должны быть объявлены как volatile
,
постскриптум ответ является более или менее общим и может быть неправильным в зависимости от языка, как уже упоминалось выше.