Ключевое слово volatile в C

Я не понимаю его значение, сколько не гуглил, везде написано мыло или теория которая без практического кода мало что говорит, кто может объяснить, что такое volatile и как его использовать со смыслом?


Ответы (1 шт):

Автор решения: HolyBlackCat

volatile заставляет компилятор не оптимизировать запись/чтение в переменную (не заменять ее на регистр а всегда писать в оперативную память, читать и писать ровно когда сказали, ...).

Если вы программируете какую-то железку, где запись по специальным адресам в памяти вызывает какие-то специальные эффекты (какой-нибудь memory-mapped IO), то volatile нужен, чтобы компилятор не сделал ничего странного с этой записью в память (не убрал ее оптимизацией, или еще что-нибудь).

Или вот еще пример: sig_atomic_t. Тут мануал говорит, что внутри обработчика std::signal можно использовать volatile переменные для связи с внешним миром.

Еще их можно использовать для бенчмарков, чтобы компилятор не выкидывал вычисления, которые вы замеряете (записать результат в volatile переменную).

Еще: до С++26 бесконечные циклы считались UB, если в их теле нет никакой связи с внешним миром, поэтому вместо пустого тела втыкали какой-нибудь i++ на volatile переменной. В C++26 разрешили бесконечные циклы с пустым телом (с непустым до сих пор нелегально). В C, я так понимаю, они в любом виде легальны.

Еще на asm ассемблерных вставках у него какой-то специальный смысл; читайте мануал.

Для чего не надо использовать:

  • Многопоточность - незнающие люди пытаются использовать их для коммуниации между потоками. Правильно - использовать std::atomic (в C++) и _Atomic (в C).
  • Подпирание костылем UB - бывает так что код крашит на ровном месте, но только с включенными оптимизациями (обычно из-за кривых рук и UB). Иногда volatile исправляет такой краш, но вместо этого лучше починить UB.
→ Ссылка