C++20 coroutine frame layout mismatch when linking object files from different compilers
0 reputation · 06 Jul 2023, 13:04 UTC
The C++20 standard defines coroutine semantics and the promise_type concept but leaves coroutine frame layout, handle representation, and intrinsic calling conventions as implementation-defined. GCC, Clang, and MSVC each emit distinct frame structures and symbol mangling for coroutine state machines, so translation units built with different toolchains cannot be linked together. Even within a single compiler family, major releases have changed the lowering strategy, breaking binary compatibility with previously compiled object files.
A library author who exposes coroutine-returning functions across a shared-library boundary must either restrict consumers to a single compiler version or provide a stable ABI wrapper. Compiler flags that affect exception handling, optimization level, or sanitizer instrumentation can also alter frame layout without diagnostic warnings.
What is the minimal set of compiler and linker flags that guarantees a consistent coroutine frame layout across translation units built with the same major compiler version? Are there any standardized or de-facto ABI specifications (such as Itanium C++ ABI extensions) that document the expected frame layout for a given toolchain? How can a build system detect and reject accidental mixing of object files with incompatible coroutine ABIs at link time?