Для C11 / C18 (я не могу говорить о C ++) функции Standard atomic_xxx()
из <stdatomic.h>
определены только для получения _Atomic
квалифицированных аргументов. Поэтому для выполнения atomic_xxx()
операций над полями вашего struct T
вам потребуется:
struct T {
_Atomic int32 high;
_Atomic int32 low;
} ;
struct T foo, bar ;
и тогда вы сможете (например) atomic_fetch_add(&foo->high, 42)
. Но bar = atomic_load(&foo)
будет неопределенным.
И наоборот, вы можете иметь:
struct T {
int32 high;
int32 low;
} ;
_Atomic struct T foo ;
struct T bar ;
, и теперь bar = atomic_load(&foo)
определено. Но доступ к любому отдельному полю в foo
не определен - независимо от того, является ли он _Atomic
.
Исходя из Стандарта, объекты _Atomic xxxx
следует рассматривать как совершенно отличные от «обычных» xxxx
объекты - они могут иметь разные размеры, представления и выравнивания. Поэтому приведение xxxx
к / от _Atomic xxxx
не более разумно, чем приведение одного struct
к / от другого, отличающегося struct
.
Но , для g cc и встроенные __atomic_xxx()
, вы можете делать все, что поддерживает процессор. Действительно, для g cc (иначе) стандартный atomic_xxx()
будет принимать аргументы, которые являются не _Atomic
квалифицированными типами и отображаются на встроенные модули. clang, с другой стороны, рассматривает передачу квалифицированного типа , а не _Atomic
стандартным функциям как ошибку. ИМХО это ошибка в g cc s <stdatomic.h>
.