`is_always_lock_free` gives `true` but `is_lock_free()` gives `false` on macOS, why?

c++, clang, lock-free, macos, stdatomic

Solution

It's a bug in the standard library libc++ (that is not present in libstdc++). Effectively it calls the builtin:

`atomic_always_lock_free` with `sizeof(__cxx_atomic_impl<A>)` which is `16`,

whereas it calls

`atomic_is_lock_free` with `sizeof(A)` which is `12`,

thus yielding inconsistent results.

Problem

I'm experimenting with C++ atomic's `std::atomic<T>::is_always_lock_free` and `std::atomic<T>::is_lock_free`. I wrote a simple struct `A` and want to know if the atomic version of `A` is lock-free: ``` #include <iostream> #include <atomic> using namespace std; struct A { int x; int y; int z; }; int main() { atomic<A> b; cout << boolalpha; cout << "b.is_always_lock_free = " << b.is_always_lock_free << endl; cout << "b.is_lock_free = " << b.is_lock_free() << endl; return 0; } ``` On a x86-64 Linux, I compiled it with g++ 9.4.0 and C++17, the output is normal: ``` b.is_always_lock_free = false b.is_lock_free = false ``` However, I also compiled it with clang++ 16.0.0 on my Mac (ARM64), the output is strange: ``` b.is_always_lock_free = true b.is_lock_free = false ``` Why `is_always_lock_free = true` and `is_lock_free = false`? If it can always be lock-free, why `b` is not lock-free?

Original source