Skip to content

Feat/modsup#1750

Open
kydos wants to merge 3 commits into
chriskohlhoff:masterfrom
kydos:feat/modsup
Open

Feat/modsup#1750
kydos wants to merge 3 commits into
chriskohlhoff:masterfrom
kydos:feat/modsup

Conversation

@kydos
Copy link
Copy Markdown

@kydos kydos commented May 29, 2026

I've had some challenges in using ASIO with a C++23 project that heavily uses modules when compiling with GCC. These PR addresses the problems I've seen. Happy to hear your comments.

zetters added 3 commits May 29, 2026 08:36
GCC 15+ (and Clang in strict module mode) reject headers included in a
named module's global module fragment when those headers declare CPO
variables in anonymous namespaces — the variables have internal linkage
(TU-local), which violates the C++20 module rules for exported entities
that reference them transitively through template constraints.

Introduce ASIO_CPO_INLINE_CONSTEXPR (in detail/config.hpp) as an opt-in
flag that replaces the anonymous-namespace singleton pattern in the four
affected CPO headers with `inline constexpr impl cpo{}`.  This is
semantically equivalent: the impl types are stateless function objects
with constexpr constructors, and inline variables have the same ODR
guarantee (one definition across all TUs) as the static_instance<> scheme.

The flag is compiler-neutral.  GCC named-module builds activate it via
-DASIO_GCC_NAMED_MODULES; other compilers may set ASIO_CPO_INLINE_CONSTEXPR
directly.  Existing builds are unaffected: the flag defaults to off and
the original anonymous-namespace path is preserved under #else.

Files changed:
  asio/include/asio/detail/config.hpp   — macro definition and detection
  asio/include/asio/prefer.hpp          — prefer CPO
  asio/include/asio/require.hpp         — require CPO
  asio/include/asio/query.hpp           — query CPO
  asio/include/asio/require_concept.hpp — require_concept CPO
Namespace-scope `const` variables in C++ have internal linkage by
default.  When asio/detail/socket_types.hpp is included in a C++20
named module's global module fragment, these variables become TU-local
entities; GCC 15+ rejects module functions that reference them
(e.g. reactive_socket_service::accept, basic_socket_streambuf::
connect_to_endpoints, reactive_socket_accept_op::do_perform).

Introduce ASIO_DETAIL_CONSTEXPR_VAR in detail/config.hpp:
  - When ASIO_CPO_INLINE_CONSTEXPR is set: expands to `inline constexpr`,
    giving these variables external linkage (C++17 inline variable).
  - Otherwise: expands to `const`, preserving the existing behaviour.

Apply the macro to all namespace-scope integer constants in
socket_types.hpp across all platform branches (Windows Runtime,
Windows/Cygwin, and POSIX), plus the three cross-platform constants
(custom_socket_option_level, enable_connection_aborted_option,
always_fail_option).
…SIO_CPO_INLINE_CONSTEXPR

The ASIO_DETAIL_CONSTEXPR_VAR macro selects between 'inline constexpr'
and 'const' via a #if on ASIO_CPO_INLINE_CONSTEXPR.  The C preprocessor
evaluates that #if when the macro is defined, not when it is expanded, so
ASIO_DETAIL_CONSTEXPR_VAR must be defined after the ASIO_GCC_NAMED_MODULES
→ ASIO_CPO_INLINE_CONSTEXPR detection block in the same file.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants