Should <stdatomic.h> work with C++? I use GCC as a cross-compiler for RTEMS targets. RTEMS uses Newlib as C library. I ported the FreeBSD version of <stdatomic.h> to Newlib and use this successfully with C/C++ and GCC pre-4.9 versions. http://svnweb.freebsd.org/base/head/sys/sys/stdatomic.h?revision=263998&view=markup Now with GCC 4.9 I have the problem that two <stdatomic.h> files are installed, e.g. find /opt/rtems-4.11/ -name stdatomic.h /opt/rtems-4.11/lib64/gcc/sparc-rtems4.11/4.9.0/include/stdatomic.h /opt/rtems-4.11/sparc-rtems4.11/include/stdatomic.h The first is provided by GCC, the second by Newlib. The GCC version is the one used. Now I get this when I compile a C++ source which indirectly includes <stdatomic.h>: sparc-rtems4.11-g++ -std=c++11 somefile.cc /opt/rtems-4.11/lib64/gcc/sparc-rtems4.11/4.9.0/include/stdatomic.h:40:9: error: '_Atomic' does not name a type typedef _Atomic _Bool atomic_bool; Is this working as intended?
The answer is no. Use atomic for C++11 code instead (since that is what the standard defines).
So I cannot use C libraries using atomics with C++ on GCC targets? With FreeBSD and clang this works fine.
(In reply to Sebastian Huber from comment #2) > So I cannot use C libraries using atomics with C++ on GCC targets? With > FreeBSD and clang this works fine. Until the c++ front-end implements _Atomic keyword, that is correct. You could exactly what FreeBSD does (but take into account gcc 4.9 c front end implementing _Atomic): 271 #if !__has_extension(c_atomic) && !__has_extension(cxx_atomic) 272 /* 273 * No native support for _Atomic(). Place object in structure to prevent 274 * most forms of direct non-atomic access. 275 */ 276 #define _Atomic(T) struct { T volatile __val; } 277 #endif But this is not correct and in most cases broken. You could also just use c++11 atomic header.
It is surely not the fault of GCC developers that C and C++ diverge more and more, but for embedded systems developers this is quite painful. It is clear that you cannot use C++ header files from C. So if you want to provide a library intended for C and C++ applications you must use C as the base line. With this C++ incompatible <stdatomic.h> you cannot do this for applications requiring atomic operations. So you are forced to provide two implementations. I don't think this is the spirit of the atomics provided by the recent C/C++ standards. GCC provides also a C++ compatible <stdbool.h> for example.
(In reply to Sebastian Huber from comment #4) > It is clear that you cannot use C++ header files from C. So if you want to > provide a library intended for C and C++ applications you must use C as the > base line. With this C++ incompatible <stdatomic.h> you cannot do this for > applications requiring atomic operations. So you are forced to provide two > implementations. Not true, I think this should work fine: #ifdef __cplusplus #include <atomic> using namespace std; #else #include <stdatomic.h> #endif atomic<int> i; int main() { atomic_store(&i, 0); return atomic_load(&i); } The fact it doesn't looks like a problem with libstdc++'s <atomic> not <stdatomic.h> I don't think we want to support the _Atomic qualifier in C++.
(In reply to Jonathan Wakely from comment #5) > #ifdef __cplusplus > #include <atomic> > using namespace std; > #else > #include <stdatomic.h> > #endif > > atomic<int> i; Doh, sorry, that should say atomic_int not atomic<int> (I changed my testcase after finding the atomic_int version failed with libstdc++)
(In reply to Sebastian Huber from comment #2) > With FreeBSD and clang this works fine. Not on my freebsd host: $ clang++ -std=c++11 a.cc In file included from a.cc:5: /usr/include/stdatomic.h:187:17: error: unknown type name '_Bool' typedef _Atomic(_Bool) atomic_bool; ^ /usr/include/stdatomic.h:187:26: error: C++ requires a type specifier for all declarations typedef _Atomic(_Bool) atomic_bool; ~~~~~~~ ^ [... and other similar errors]
(In reply to Sebastian Huber from comment #4) > I don't think this is the spirit of the atomics provided > by the recent C/C++ standards. The atomics are supposed to be roughly source-compatible, in that the relevant headers for each language define types and functions and macros with the same names and equivalent effects. But the two languages define those features in different headers. If you want to use atomics in C, use <stdatomic.h>, and if you want to use them in C++, use <atomic> and appropriate using-declarations or a using-directive. I've created Bug 60940 for the libstdc++ issue.
(In reply to Jonathan Wakely from comment #5) > (In reply to Sebastian Huber from comment #4) > > It is clear that you cannot use C++ header files from C. So if you want to > > provide a library intended for C and C++ applications you must use C as the > > base line. With this C++ incompatible <stdatomic.h> you cannot do this for > > applications requiring atomic operations. So you are forced to provide two > > implementations. > > Not true, I think this should work fine: > > #ifdef __cplusplus > #include <atomic> > using namespace std; > #else > #include <stdatomic.h> > #endif > > atomic<int> i; > > int main() > { > atomic_store(&i, 0); > return atomic_load(&i); > } > > The fact it doesn't looks like a problem with libstdc++'s <atomic> not > <stdatomic.h> > > I don't think we want to support the _Atomic qualifier in C++. Ok, but if I create a data structure definition like for example in example.h: #ifdef __cplusplus #include <atomic> using namespace std; #else #include <stdatomic.h> #endif struct s { atomic_int i; }; Who guarantees that this definition is binary compatible in C and C++?
(In reply to Sebastian Huber from comment #9) > Who guarantees that this definition is binary compatible in C and C++? The compiler/stdlib implementors. The same people who you want to guarantee that if you include <stdatomic.h> with a C++ compiler that understands the _Atomic keyword that the results will be binary compatible with C code including the same header.
Ok, I will use this #ifdef __cplusplus #include <atomic> using namespace std; #else #include <stdatomic.h> #endif approach, but from my point of view this is quite an unsatisfactory user experience.
Is the status really "wontfix"? This makes any C library which uses stdatomic.h incompatible with g++ (and more and more C code uses stdatomic.h) which is rather bothersome. clang doesn't have this issue. What prevent stdatomic.h to detect if it is included in C++ mode and includes C++ <atomic> instead?
(In reply to Patrick Pelissier from comment #12) > Is the status really "wontfix"? > > This makes any C library which uses stdatomic.h incompatible with g++ (and <stdatomic.h> is not part of the C++ standard. > more and more C code uses stdatomic.h) which is rather bothersome. clang > doesn't have this issue. Clang allows the C keyword _Atomic in C++. That's not part of the C++ standard either > What prevent stdatomic.h to detect if it is included in C++ mode and > includes C++ <atomic> instead? Even if it did that, it wouldn't guarantee that C's atomic_int and C++'s std::atomic_int are compatible. So you'd still need to rely on non-portable implementation-specific assumptions.
Note, stdatomic.h is now in C++20.