swiftlang / swiftlang/swift-corelibs-libdispatch

C++23 `<stdatomic.h>` is incompatible with libdispatch's `_Atomic` shim

Open
#940 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C
Stars
2.6k
Forks
496
Avg merge
2d 6h
Merged PRs (30d)
3

Description

I was using swift-corelibs-libdispatch as part of a broader Bazel-based
system. While porting that project from C++20 to C++23, I found a problem with
the way libdispatch uses <stdatomic.h>.

Steps to validate (in standalone swift-corelibs-libdispatch)

  1. Edit CMakeLists.txt and set CMAKE_CXX_STANDARD to 23.
  2. Build swift-corelibs-libdispatch.
  3. Check whether the build succeeds.

Expected

Build succeeds.

Actual

Build fails with both libstdc++ and libc++.

With libstdc++, the failure looks like:

In file included from /path/to/swift-corelibs-libdispatch/src/block.cpp:31:
In file included from /path/to/swift-corelibs-libdispatch/src/internal.h:667:
In file included from /path/to/swift-corelibs-libdispatch/src/shims.h:220:
In file included from /path/to/swift-corelibs-libdispatch/src/shims/atomic.h:41:
In file included from /usr/lib/gcc/x86_64-redhat-linux/15/../../../../include/c++/15/stdatomic.h:36:
In file included from /usr/lib/gcc/x86_64-redhat-linux/15/../../../../include/c++/15/atomic:52:
In file included from /usr/lib/gcc/x86_64-redhat-linux/15/../../../../include/c++/15/bits/atomic_base.h:38:
/usr/lib/gcc/x86_64-redhat-linux/15/../../../../include/c++/15/new:230:3: error: templates must have C++ linkage
  230 |   template<typename _Tp>
      |   ^~~~~~~~~~~~~~~~~~~~~~
/path/to/swift-corelibs-libdispatch/src/internal.h:326:1: note: extern "C" language linkage specification begins here
  326 | __BEGIN_DECLS
      | ^
/usr/include/sys/cdefs.h:140:24: note: expanded from macro '__BEGIN_DECLS'
  140 | # define __BEGIN_DECLS  extern "C" {
      |                         ^
In file included from /path/to/swift-corelibs-libdispatch/src/block.cpp:31:
In file included from /path/to/swift-corelibs-libdispatch/src/internal.h:667:
In file included from /path/to/swift-corelibs-libdispatch/src/shims.h:220:
In file included from /path/to/swift-corelibs-libdispatch/src/shims/atomic.h:41:
In file included from /usr/lib/gcc/x86_64-redhat-linux/15/../../../../include/c++/15/stdatomic.h:36:
In file included from /usr/lib/gcc/x86_64-redhat-linux/15/../../../../include/c++/15/atomic:52:
In file included from /usr/lib/gcc/x86_64-redhat-linux/15/../../../../include/c++/15/bits/atomic_base.h:40:
/usr/lib/gcc/x86_64-redhat-linux/15/../../../../include/c++/15/bits/move.h:49:3: error: templates must have C++ linkage
   49 |   template<typename _Tp>
      |   ^~~~~~~~~~~~~~~~~~~~~~

With libc++, the failure looks like:

In file included from /path/to/swift-corelibs-libdispatch/src/block.cpp:31:
In file included from /path/to/swift-corelibs-libdispatch/src/internal.h:667:
In file included from /path/to/swift-corelibs-libdispatch/src/shims.h:220:
In file included from /path/to/swift-corelibs-libdispatch/src/shims/atomic.h:41:
In file included from /usr/include/c++/v1/stdatomic.h:131:
In file included from /usr/include/c++/v1/atomic:605:
In file included from /usr/include/c++/v1/__atomic/aliases.h:12:
In file included from /usr/include/c++/v1/__atomic/atomic.h:12:
In file included from /usr/include/c++/v1/__atomic/atomic_sync.h:12:
In file included from /usr/include/c++/v1/__atomic/contention_t.h:12:
In file included from /usr/include/c++/v1/__atomic/support.h:108:
In file included from /usr/include/c++/v1/__atomic/support/c11.h:12:
In file included from /usr/include/c++/v1/__atomic/memory_order.h:13:
/usr/include/c++/v1/__type_traits/is_same.h:21:1: error: templates must have C++ linkage
   21 | template <class _Tp, class _Up>
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/path/to/swift-corelibs-libdispatch/src/internal.h:326:1: note: extern "C" language linkage specification begins here
  326 | __BEGIN_DECLS
      | ^

Environment

Tested on Linux x86_64 (Fedora 43) with:

  • swift-corelibs-libdispatch at 330412f6d906b6a6c39cb70bd342fd9134fca65f
  • Clang 21
  • C++23
  • libstdc++ repro: clang++ using GCC 15 C++ headers
  • libc++ repro: clang++ -stdlib=libc++ using /usr/include/c++/v1

Root cause

src/shims/atomic.h contains an internal shim built around Clang C _Atomic
storage and C11 atomic operations.

In C++23, both libstdc++ and libc++ implement <stdatomic.h> in C++ mode
using the C++ atomics model instead of the old C11-style interface that
libdispatch's shim expects.

That does not match what libdispatch's shim expects. In practice, this causes
src/block.cpp to fail to compile through the include chain:

src/block.cpp -> src/internal.h -> src/shims.h -> src/shims/atomic.h -> <stdatomic.h>

Possible solution

One possible fix would be to make src/shims/atomic.h use private libdispatch
atomic aliases instead of directly relying on the public atomic_* names from
<stdatomic.h>.

For C and older C++ modes, those aliases could continue to map to
<stdatomic.h>.

For C++23 and newer, they could instead map directly to Clang
__c11_atomic_* builtins and __ATOMIC_* memory-order constants. That would
preserve the shim's current _Atomic-based model without depending on the
C++23 std::atomic-based behavior of <stdatomic.h>.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with src/shims/atomic.h and trace the include chain from src/block.cpp through src/internal.h and src/shims.h. Review how the shim uses <stdatomic.h> in C++23, then validate the change by setting CMAKE_CXX_STANDARD to 23 and building with both libstdc++ and libc++; done means both builds succeed.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.