Последнее обновление:2026-10-12
C++ ключевое слово volatile¶
Об авторе:¶
Личный официальный аккаунт:

1.volatile¶
Переменная, модифицированная volatile, при операциях чтения и записи может вызывать некоторые наблюдаемые побочные эффекты, причём эти наблюдаемые побочные эффекты определяются факторами вне программы.
2.Применение volatile¶
(1)Аппаратные регистры параллельных устройств (например, регистры состояния). Пусть нужно инициализировать устройство, и один из его регистров находится по адресу 0xff800000.
int *output = (unsigned int *)0xff800000; //定义一个IO端口;
int init(void)
{
int i;
for(i=0;i< 10;i++)
{
*output = i;
}
}
(2)Переменные, к которым обращается подпрограмма обработки прерывания;
static int i=0;
int main()
{
while(1)
{
if(i) dosomething();
}
}
/* Interrupt service routine */
void IRS()
{
i=1;
}
(3)Переменные, разделяемые несколькими задачами в многопоточном приложении. Когда несколько потоков разделяют некоторую переменную и её значение может быть изменено одним из потоков, её следует объявлять volatile. Роль этого — не дать компилятору оптимизацией поместить переменную из памяти в регистр CPU, когда после изменения переменной одним потоком она не будет своевременно синхронизирована с другими потоками, что приведёт к ошибке программы. volatile означает, что компилятор при каждой операции с этой переменной обязан действительно считывать её из памяти, а не использовать уже находящееся в регистре значение. Пример:
volatile bool bStop=false; //bStop 为共享全局变量
//第一个线程
void threadFunc1()
{
...
while(!bStop){...}
}
//第二个线程终止上面的线程循环
void threadFunc2()
{
...
bStop = true;
}
Знание сценариев применения volatile — эффективный способ отличить программиста C/C++ от программиста встраиваемых систем: разработчики встраиваемых систем постоянно имеют дело с аппаратурой, прерываниями, RTOS и т. д., где всё это требует volatile-переменных; непонимание volatile принесёт катастрофу при проектировании программ.
3.Частые вопросы о volatile¶
По приведённым ниже вопросам можно понять, действительно ли кандидат разбирается в volatile. (1)Может ли параметр быть одновременно const и volatile? Почему? Да. Пример — регистр состояния, доступный только для чтения. Он volatile, потому что может неожиданно изменяться. Он const, потому что программа не должна пытаться его изменять.
(2)Может ли указатель быть volatile? Почему? Да, хотя это нечасто встречается. Пример — когда подпрограмма обработки прерывания изменяет указатель на буфер.
(3)Что не так с приведённой ниже функцией?
Этот код немного экстравагантен: его цель — вернуть квадрат значения, на которое указывает указатель ptr; но поскольку ptr указывает на volatile-параметр, компилятор сгенерирует код, подобный следующему: Поскольку значение *ptr может неожиданно измениться, a и b могут оказаться разными. В результате этот код может вернуть вовсе не то значение квадрата, которое вы ожидаете! Правильный код таков:4.Использование volatile¶
-
Ключевое слово volatile — это модификатор типа; переменные объявленного с его помощью типа могут изменяться факторами, неизвестными компилятору (операционная система, аппаратура, другие потоки и т. д.). Поэтому volatile сообщает компилятору, что такие объекты не следует оптимизировать.
-
Переменная, объявленная с ключевым словом volatile, при каждом обращении должна считывать значение из памяти (переменные без модификатора volatile из-за оптимизаций компилятора могут браться из регистров CPU)
- const может быть volatile (например, регистр состояния, доступный только для чтения)
- Указатель может быть volatile
Код для изучения:
Похожие темы¶
- C++ чисто виртуальные функции и абстрактные классы | C++那些事
- C++ утверждения assert | C++那些事
- C++ битовые поля | C++那些事
- Реализация полиморфизма C++ на языке C | C++那些事
- C++ константы const и его модификация | C++那些事
- C++ всё семейство const | C++那些事
- C++ оператор разыменования * | C++那些事
- C++ инициализация и присваивание | C++那些事
- C++ возврат нескольких значений | C++那些事
- C++ ключевое слово mutable | C++那些事