By my reading of the standard,
*(_Atomic TYPE*)&(TYPE){0}
(in words, casting a pointer to a non-atomic to a pointer to a corresponding atomic and dereferencing) isn't supported.
Do gcc and/or clang recognize it as an extension if TYPE
is/isn't lock-free? (Question 1)
Second and related question: I was under the impression that if TYPE
couldn't be implemented as a lock free atomic, a lock would need to be embedded in the corresponding _Atomic TYPE
. But if I make TYPE
a largish struct, then on both clang
and gcc
it has the same size as _Atomic TYPE
.
Code for both problems:
#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));
}
Now, if I compile the above snippet with -DSTRUCT
, both gcc and clang keep the both the struct and its atomic variant at the same size, and they generate a call to a function named __atomic_store
for the store (resolved by linking with -latomic
).
How does this work if no lock is embedded in the _Atomic
version of the struct? (Question 2)