In a C++ project, I’m using a C library which includes some C11 headers. It won’t compile with GCC. See this simple code:

  1. // main.cc
  2. #include <stdatomic.h>
  3. int main()
  4. {
  5. printf("Hello world\n");
  6. return 0;
  7. }

Running gcc main.cc -lstdc++, it complains: error: ‘_Atomic’ does not name a type. However, clang main.cc -lstdc++ works like a charm. I’m wondering what makes the difference, and how can I compile it with gcc?

clang

clang main.cc -lstdc++
编译正常,生成a.out, 运行a.out,打印出“Hello world”

gcc

gcc main.cc -lstdc++
编译出错:
image.png

That library can’t be used as is in C++. Different languages now more than ever. You’d need to wrap it.
这是因为stdatomic.h是c11引入的,该库不能按原样在 C++ 中使用。你需要把它包起来。

To wrap C headers that use atomics, you may use the other spelling of _Atomic and define a macro that transforms this to valid C++:

  1. #ifndef __cplusplus
  2. # include <stdatomic.h>
  3. #else
  4. # include <atomic>
  5. # define _Atomic(X) std::atomic< X >
  6. #endif
  7. int foo(_Atomic(unsigned)* toto);

Both atomics interfaces have been developed in sync between the two committees, so besides syntax problems these should be binary compatible on any reasonable platform that provides C and C++.