volatile
Указатель NULL не имеет особого смысла, поскольку никто не собирается его разыменовывать.
Но если я сделаю это выражение более понятным (это пример микроконтроллера STM32)
volatile uint32_t *GPIOA_CRL = (volatile uint32_t *)0x40010800UL;
Я объявляю volatile
указатель GPIO_CLR
на объект uint32_t
. Присвоение преобразует адрес этого аппаратного регистра, заданного длинной без знака, в тип указателя.
0x40010800UL
- адрес аппаратного регистра
(volatile uint32_t *)
- преобразует длинный беззнаковый адрес в указатель
Тогда я могу установить или прочитать значение этого регистра.
Почему я определил этот указатель как volatile
? Потому что это может быть изменено аппаратным обеспечением, и компилятор не будет знать об этом. Поэтому volatile заставит компилятор читать хранилища значений по этому адресу перед каждым использованием (когда я разыменовываю этот указатель) и сохранять его после каждого изменения. В противном случае компилятор может оптимизировать эти операции чтения и записи, поскольку он не увидит никакого эффекта в обычном пути выполнения программы.