volatile (C++)
Квалификатор типа, который используется для объявления о том, что объект может быть изменен в программе аппаратным обеспечением.
volatile declarator ;
Заметки
Ключ компилятора /volatile позволяет изменить интерпретацию этого ключевого слова компилятором.
Visual Studio интерпретирует ключевое слово volatile по-разному, в зависимости от целевой архитектуры. В архитектуре ARM, если параметр компилятора /volatile не указан, компилятор действует так же, как если бы был задан параметр /volatile:iso. Во всех остальных архитектурах, кроме ARM, если параметр компилятора /volatile не указан, то компилятор действует так же, как если бы был задан параметр /volatile:ms. Таким образом, при работе с памятью, совместно используемой потоками, для всех архитектур, кроме ARM, настоятельно рекомендуется указывать параметр /volatile:iso и использовать явные примитивы синхронизации и встроенные функции компилятора.
Квалификатор volatile позволяет предоставлять доступ к областям памяти, которые используются асинхронными процессами, например обработчиками прерываний.
Если квалификатор volatile используется в переменной, для которой также указано ключевое слово __restrict, то приоритет имеет квалификатор volatile.
Если член struct помечен как volatile, то ключевое слово volatile распространяется на всю структуру. Если структура не имеет длины, которую в текущей архитектуре можно скопировать с помощью одной инструкции, то квалификатор volatile может быть полностью утерян для этой структуры.
Ключевое слово volatile может не оказывать воздействия на поле, если выполняется одно из следующих условий.
Длина поля с ключевым словом volatile превышает максимальный размер, который в текущей архитектуре может быть скопирован с помощью одной инструкции.
Длина самого внешнего окружающего объекта struct — или если он является членом объекта struct, который может быть также вложенным — превышает максимальный размер, который в текущей архитектуре может быть скопирован с помощью одной инструкции.
Хотя процессор не меняет порядок некэшированных обращений к памяти, некэшированные переменные должны быть помечены как volatile, чтобы гарантировать, что компилятор не изменит порядок обращений к памяти.
Объекты, которые были объявлены как volatile, не используются в некоторых способах оптимизации, поскольку их значения могут измениться в любое время. При запросе объекта с ключевым словом volatile система всегда считывает его текущее значение, даже если оно запрашивалось в предшествовавшей инструкции. Кроме того, значение объекта записывается непосредственно при присваивании.
Блок, относящийся к стандарту ISO
Если вы знакомы с ключевым словом C# volatile или разбираетесь в поведении volatile в более ранних версиях Visual C++, вам необходимо учитывать, что в стандарте ISO для языка C++11 ключевое слово volatile отличается. В Visual Studio такое ключевое слово поддерживается, если установлен параметр компилятора /volatile:iso. (Для архитектуры ARM он установлен по умолчанию). Ключевое слово volatile в коде, создаваемом согласно стандарту ISO для языка C ++11, должно использоваться только для аппаратного доступа; его использование для взаимодействия между потоками не допускается. Для взаимодействия между потоками необходимо использовать такие механизмы, как std::atomic<T> из стандартной библиотеки шаблонов C++.
Блок, относящийся только к системам Microsoft
Если используется параметр компилятора /volatile:ms (он установлен по умолчанию, если целевой является любая архитектура, кроме ARM), то компилятор создает дополнительный код для сохранения порядка между ссылками на объекты с ключевым словом volatile в дополнение к сохранению порядка ссылок на другие глобальные объекты. В частности:
Запись в объект с ключевым словом volatile (т. н. "запись в изменяемый объект") имеет семантику освобождения. Это означает, что ссылка на глобальный или статический объект, которая находится в последовательности инструкций перед записью в объект с ключевым словом volatile, в скомпилированном двоичном файле будет находиться до записи в изменяемый объект.
Считывание из объекта с ключевым словом volatile (т. н. "считывание из изменяемого объекта") имеет семантику получения. Это означает, что ссылка на глобальный или статический объект, которая находится в последовательности инструкций после считывания из объекта с ключевым словом volatile, в скомпилированном двоичном файле будет находиться после считывания из изменяемого объекта.
Благодаря этому объекты с ключевым словом volatile могут использоваться для блокировки и освобождения памяти в многопоточных приложениях.
Примечание
Если код строится с расчетом на гарантии, которые дает параметр компилятора /volatile:ms, то такой код не может переноситься на другие платформы.