Один из способов понять изменчивую переменную - представить, что это виртуальное свойство;пишет и даже читает может делать то, о чем не может знать компилятор.Фактически сгенерированный код для записи / чтения энергозависимой переменной - это просто запись в память или чтение (*), но компилятор должен считать код непрозрачным;он не может делать никаких предположений, при которых он может быть излишним.Проблема не просто в том, что скомпилированный код замечает, что что-то вызвало изменение переменной.В некоторых системах даже чтение из памяти может «делать» вещи.
(*) В некоторых компиляторах изменяемые переменные могут добавляться, вычитаться, увеличиваться, уменьшаться и т. Д. Как отдельные операции.Вероятно, компилятору полезно скомпилировать:
volatilevar++;
как
inc [_volatilevar]
, поскольку последняя форма может быть атомарной на многих микропроцессорах (хотя и не на современных многоядерных ПК).Однако важно отметить, что если бы оператор был:
volatilevar2 = (volatilevar1++);
, то правильный код не был бы:
mov ax,[_volatilevar1] ; Reads it once
inc [_volatilevar] ; Reads it again (oops)
mov [_volatilevar2],ax
или
mov ax,[_volatilevar1]
mov [_volatilevar2],ax ; Writes in wrong sequence
inc ax
mov [_volatilevar1],ax
, а скорее
mov ax,[_volatilevar1]
mov bx,ax
inc ax
mov [_volatilevar1],ax
mov [_volatilevar2],bx
Написание исходного кода по-другому позволило бы генерировать более эффективный (и, возможно, более безопасный) код.Если 'volatilevar1' не возражал против прочтения дважды, а 'volatilevar2' не возражал против написания перед volatilevar1, то разбиение оператора на
volatilevar2 = volatilevar1;
volatilevar1++;
позволит быстрее и, возможно, безопаснее код.1024 *