Spec-Zone.ru › GCC 8

6.44 Когда обращается к объекту типа 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-8.5.0/gcc/Volatiles.html

Spec-Zone.ru

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