Spec-Zone.ru › GCC 6

6.43 Когда обращаются к изменяемому объекту?

В языке C существуют изменяемые объекты. К ним обычно обращаются через указатели и используются для доступа к аппаратуре или межпотоковой коммуникации. Стандарт рекомендует компиляторам воздерживаться от оптимизаций, касающихся обращений к изменяемым объектам, но оставляет за реализацией определение того, что представляет собой обращение к изменяемому объекту. Минимальное требование состоит в том, что в точке последовательности все предыдущие обращения к изменяемым объектам должны быть стабилизированы, и не должно происходить последующих обращений. Таким образом, реализация свободна переупорядочивать и объединять обращения к изменяемым объектам, которые происходят между точками последовательности, но не может делать это для обращений через точку последовательности. Использование 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;

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

volatile int *src = somevalue;
*src;

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

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

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

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

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

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

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

Spec-Zone.ru

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