Spec-Zone.ru › GCC 12

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 битовые поля для доступа к оборудованию.

Далее: Использование языка ассемблера с C, Предыдущее: Inline, Вверх: Расширения языка C [Оглавление][Индекс]

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

Spec-Zone.ru

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