Spec-Zone.ru › GCC 14

6.47 Когда обращаются к объекту 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;

Такие выражения являются rvalues, и 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-14.2.0/gcc/Volatiles.html

Spec-Zone.ru

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