Ответ 1
Указатель формы
volatile int* p;
это указатель на int
который компилятор будет рассматривать как volatile
. Это означает, что компилятор будет предполагать, что переменная, на которую указывает p
может измениться, даже если в исходном коде ничего нет, чтобы предположить, что это может произойти. Например, если я установлю p
для указания на обычное целое число, то каждый раз, когда я читаю или пишу *p
компилятор осознает, что значение могло неожиданно измениться.
Существует еще один вариант использования volatile int*
: если вы объявляете int
как volatile
, вам не следует указывать на него обычным int*
. Например, это плохая идея:
volatile int myVolatileInt;
int* ptr = &myVolatileInt; // Bad idea!
Причина этого заключается в том, что компилятор C больше не помнит, что переменная, на которую указывает ptr
является volatile
, поэтому он может неправильно кэшировать значение *p
в регистре. Фактически в C++ приведенный выше код является ошибкой. Вместо этого вы должны написать
volatile int myVolatileInt;
volatile int* ptr = &myVolatileInt; // Much better!
Теперь компилятор запоминает, что ptr
указывает на volatile int
, поэтому он не будет (или не должен!) Пытаться оптимизировать доступ через *ptr
.
Одна последняя деталь - указатель, который вы обсуждали, является указателем на volatile int
. Вы также можете сделать это:
int* volatile ptr;
Это говорит о том, что сам указатель является volatile
, что означает, что компилятор не должен пытаться кэшировать указатель в памяти или пытаться оптимизировать значение указателя, поскольку сам указатель может быть переназначен чем-то другим (аппаратным обеспечением и т.д.). Вы можете комбинировать это вместе, если вы хотите получить этого зверя:
volatile int* volatile ptr;
Это говорит о том, что указатель и указатель могут быть неожиданно изменены. Компилятор не может оптимизировать сам указатель и не может оптимизировать то, на что он указывает.
Надеюсь это поможет!