По моему прочтению стандарта,
*(_Atomic TYPE*)&(TYPE){0}
(на словах приведение указателя на неатомарный указатель на соответствующий атомарный элемент и разыменование) не поддерживается.
gcc и / или clang распознают его как расширение, если TYPE
не заблокирован? (Вопрос 1)
Второй и связанный с этим вопрос: у меня сложилось впечатление, что, если TYPE
не может быть реализован как атомарный элемент без блокировки, блокировка должна быть встроена в соответствующий _Atomic TYPE
. Но если я сделаю TYPE
большой структурой, то и на clang
, и на gcc
она будет иметь тот же размер, что и _Atomic TYPE
.
Код для обеих проблем:
#include <stdatomic.h>
#include <stdio.h>
#if STRUCT
typedef struct {
int x;
char bytes[50];
} TYPE;
#else
typedef int TYPE;
#endif
TYPE x;
void f (_Atomic TYPE *X)
{
*X = (TYPE){0};
}
void use_f()
{
f((_Atomic TYPE*)(&x));
}
#include <stdio.h>
int main()
{
printf("%zu %zu\n", sizeof(TYPE), sizeof(_Atomic TYPE));
}
Теперь, если я скомпилирую приведенный выше фрагмент с -DSTRUCT
, и gcc, и clang сохранят как структуру, так и ее атомарный вариант одинакового размера, и сгенерируют вызов функции с именем __atomic_store
для хранилища ( разрешается связыванием с -latomic
).
Как это работает, если в версии _Atomic
структуры нет встроенной блокировки? (Вопрос 2)