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 STRUCTtypedef struct { int x; char bytes[50];} TYPE;#elsetypedef int TYPE;#endifTYPE 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)