Compiling with built-in stdatomic vs stdatomic.h

Hi all-

I have a weird issue compiling a program using clang 13.0.0 on Fedora Linux with the <stdatomic.h> header. I have a sample in this pastebin but what it boils down to is, the program does not compile if stdatomic.h is present on the system.

On the current release version of Fedora (35), stdatomic.h is not present, but under Rawhide (will be Fedora 36), it is. Because of that, clang, per works fine when stdatomic.h is renamed, but when I put it back the program fails to compile, complaining of ./atom2.cpp:8:5: error: use of undeclared identifier 'atomic_compare_exchange_strong'.

I’m wondering if there’s some way to tell clang “ignore stdatomic.h on the system, use the internal one”, or if there’s some issue with the way clang is handling the header.

Thanks for any insight!


You can try using -ffreestanding, but that might be too big a hammer.

You can also try a hack like:

#include <stddef.h>  // Include headers used by Clang's stdatomic.h first
#include <stdint.h>
#undef __STDC_HOSTED__
#define __STDC_HOSTED__ 0
#include <stdatomic.h>
#undef __STDC_HOSTED__
#define __STDC_HOSTED__ 1

As for “system” stdatomic.h, does GCC use it? You can use -MD -MF - (both for GCC and for Clang) to see what stdatomic.h headers are involved.

Hi Hubert-

Interestingly, neither the big hammer or the hack worked, same error in the same spot.

I brought this up on the Fedora Mailing List and got a response from the person who added stdatomic.h. The main point Jonathan makes is:

Clang is at fault here. <stdatomic.h> does not exist in C++ up to and including the current C++20 standard, so Clang should not assume it’s present or usable. In C++23 there is now a <stdatomic.h> header in the C++ library for compatibility. That’s what I added to GCC, and that’s what Clang is now picking up.

Yes, the suggestions I made were in the context of encountering a stdatomic.h from the “system”/toolchain C (not C++) headers. It sounds like the issue you are having is that the C++23 header from GCC is being picked up as intended and that it does not provide the declarations because you are not in C++23 mode. I would suggest that the GCC header should, for C++ before C++23, either:

  • provide the declarations as an extension or produce a #error; or
  • check if there is another stdatomic.h to fall back to and #include_next.