swiftlang / swiftlang/swift-corelibs-libdispatch
C++23 `<stdatomic.h>` is incompatible with libdispatch's `_Atomic` shim
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)
- Edit
CMakeLists.txtand setCMAKE_CXX_STANDARDto23. - Build
swift-corelibs-libdispatch. - 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-libdispatchat 330412f6d906b6a6c39cb70bd342fd9134fca65f- Clang 21
- C++23
libstdc++repro:clang++using GCC 15 C++ headerslibc++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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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