Casting pointers to _Atomic pointers and _Atomic sizes

_Atomic changes alignment in some corner cases on Clang, and GCC will likely be fixed in the future as well (PR 65146). In these cases, adding _Atomic through a cast does not work (which is fine from a C standard point of view because it is undefined behavior, as you pointed out).

If the alignment is correct, it is more appropriate to use the __atomic builtins, which have been designed for exactly this use case:

  • Built-in Functions for Memory Model Aware Atomic Operations

As described above, this will not work in cases where the ABI provides insufficient alignment for plain (non-atomic) types, and where _Atomic would change alignment (with Clang only for now).

These builtins also work in case of non-atomic types because they use out-of-line locks. This is also the reason why no additional storage is required for _Atomic types, which use the same mechanism. This means that there is some unnecessary contention due to unintentional sharing of the locks. How these locks are implemented is an implementation detail which could change in future versions of libatomic.

In general, for types with atomic builtins that involve locking, using them with shared or aliased memory mappings does not work. These builtins are not async-signal-safe, either. (All these features are technically outside the C standard anyway.)