Spec-Zone.ru › GCC 4

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

Spec-Zone.ru

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