Spec-Zone.ru › GCC 13

6.46 Когда обращаются к объекту volatile?

C имеет понятие объектов volatile. К ним обычно обращаются через указатели и их используют для доступа к аппаратному обеспечению или межпотоковой коммуникации. Стандарт рекомендует компиляторам воздерживаться от оптимизаций, касающихся доступа к объектам volatile, но оставляет определение того, что считается доступом к volatile, на усмотрение реализации. Минимальное требование заключается в том, что в точке последовательности все предыдущие обращения к объектам volatile должны быть стабилизированы, и никаких последующих обращений не должно происходить. Таким образом, реализация свободна в переупорядочивании и объединении обращений к volatile, которые происходят между точками последовательности, но не может делать этого для обращений через точку последовательности. Использование volatile не позволяет нарушать ограничение на обновление объектов несколько раз между двумя точками последовательности.

Доступы к не-volatile объектам не упорядочены относительно обращений к volatile. Вы не можете использовать volatile объект как барьер памяти для упорядочивания последовательности записей в не-volatile память. Например:

int *ptr = something;
volatile int vobj;
*ptr = something;
vobj = 1;

Если *ptr и vobj не могут быть алиасами, не гарантируется, что запись в *ptr произойдёт к тому времени, когда произойдёт обновление vobj. Если вам нужна эта гарантия, вы должны использовать более сильный барьер памяти, например:

int *ptr = something;
volatile int vobj;
*ptr = something;
asm volatile ("" : : : "memory");
vobj = 1;

Скалярный volatile объект читается, когда к нему обращаются в контексте void:

volatile int *src = somevalue;
*src;

Такие выражения являются rvalue, и GCC реализует это как чтение volatile объекта, на который указывает указатель.

Присваивания также являются выражениями и имеют rvalue. Однако при присваивании скалярному volatile объекту, volatile объект не перечитывается, независимо от того, используется ли rvalue выражения присваивания или нет. Если rvalue выражения присваивания используется, то значение — это значение, присвоенное volatile объекту. Например, нет чтения vobj во всех следующих случаях:

int obj;
volatile int vobj;
vobj = something;
obj = vobj = something;
obj ? vobj = onething : vobj = anotherthing;
obj = (something, vobj = anotherthing);

Если вам нужно прочитать volatile объект после того, как присваивание произошло, вы должны использовать отдельное выражение с промежуточной точкой последовательности.

Поскольку битовые поля не адресуемы индивидуально, битовые поля volatile могут быть неявно считаны при записи или при доступе к соседним битовым полям. Операции с битовыми полями могут быть оптимизированы таким образом, что соседние битовые поля будут только частично обработаны, если они охватывают границу хранилища. По этим причинам не рекомендуется использовать битовые поля volatile для доступа к аппаратуре.

© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-13.3.0/gcc/Volatiles.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API