Краткий ответ: ключевое слово volatile
означает , а не означает "не оптимизировать".Это нечто совершенно другое.Он сообщает компилятору, что переменная может быть изменена чем-то, что не видно компилятору в обычном потоке программы.Например:
- Может быть изменено аппаратно - обычно регистры отображаются в адресном пространстве памяти
- Может быть изменено функцией, которая никогда не вызывается - например, подпрограмма прерывания
- Переменная может быть изменена другим процессом или оборудованием - например, совместно используемой памятью в многопроцессорных / многоядерных системах
Энергозависимая переменная должна считываться из своего места хранения каждый раз, когда онаиспользуется и сохраняется при каждом изменении.
Здесь у вас есть пример:
int foo(volatile int z)
{
return z + z + z + z;
}
int foo1(int z)
{
return z + z + z + z;
}
и полученный код (опция оптимизации -O0)
foo(int):
push rbp
mov rbp, rsp
mov DWORD PTR [rbp-4], edi
mov edx, DWORD PTR [rbp-4]
mov eax, DWORD PTR [rbp-4]
add edx, eax
mov eax, DWORD PTR [rbp-4]
add edx, eax
mov eax, DWORD PTR [rbp-4]
add eax, edx
pop rbp
ret
foo1(int):
push rbp
mov rbp, rsp
mov DWORD PTR [rbp-4], edi
mov eax, DWORD PTR [rbp-4]
sal eax, 2
pop rbp
ret
Разница очевидна, я думаю.Переменная volatile читается 4 раза, а volatile читается один раз, затем умножается на 4.
Вы можете играть здесь: https://godbolt.org/g/RiTU4g
В большинстве случаев, если программа не запускаетсякогда вы включаете оптимизацию компилятора, в вашем коде появляются скрытые UB.Вы должны отлаживать столько времени, сколько нужно, чтобы обнаружить их все.Правильно написанная программа должна работать на любом уровне оптимизации.
Имейте в виду, что "volatile" не означает или не гарантирует целостность и атомарность .