I do not know if clang++ would end up with analogous issues. I happened to have started with g++15 for seeing if I could build the std std.compat module from the source for doing so. gcc got support for std.compat and std builds in 15.1 .
Note that I'm using a aarch64 context here and my lang/gcc15 has the recent patch that that has been committed to lang/gcc15-devel that allows the toolchain to be built for aarch64. (I doubt that use of lang/gcc15-devel would be any different.) # g++15 -std=c++23 -O2 -fmodules -fsearch-include-path -fmodule-only -c bits/std.cc /usr/local/lib/gcc15/include/c++/bits/std.cc:3351:14: error: exporting 'int feclearexcept(int)' that does not have external linkage 3351 | using std::feclearexcept; | ^~~~~~~~~~~~~ In file included from /usr/local/lib/gcc15/include/c++/fenv.h:41, from /usr/local/lib/gcc15/include/c++/cfenv:43, from /usr/local/lib/gcc15/include/c++/aarch64-portbld-freebsd15.0/bits/stdc++.h:128, from /usr/local/lib/gcc15/include/c++/bits/std.cc:30: /usr/include/fenv.h:84:1: note: 'int feclearexcept(int)' declared here with internal linkage 84 | feclearexcept(int __excepts) | ^~~~~~~~~~~~~ /usr/local/lib/gcc15/include/c++/bits/std.cc:3352:14: error: exporting 'int fegetenv(fenv_t*)' that does not have external linkage 3352 | using std::fegetenv; | ^~~~~~~~ . . . and so on for supporting building from (for example): /usr/local/lib/gcc15/include/c++/bits/std.cc <http://std.cc/> : . . . // 28.3 <cfenv> export C_LIB_NAMESPACE { #ifdef _GLIBCXX_USE_C99_FENV using std::feclearexcept; using std::fegetenv; using std::fegetexceptflag; using std::fegetround; using std::feholdexcept; using std::fenv_t; using std::feraiseexcept; using std::fesetenv; using std::fesetexceptflag; using std::fesetround; using std::fetestexcept; using std::feupdateenv; using std::fexcept_t; #endif } . . . g++15 has: /usr/local/lib/gcc15/include/c++/cfenv : . . . #include <bits/c++config.h> #if _GLIBCXX_HAVE_FENV_H # include <fenv.h> #endif . . . /usr/local/lib/gcc15/include/c++/fenv.h : . . . #include <bits/c++config.h> #if _GLIBCXX_HAVE_FENV_H # include_next <fenv.h> #endif . . . /usr/local/lib/gcc15/include/c++/aarch64-portbld-freebsd15.0/bits/c++config.h does have: /* Define to 1 if you have the <fenv.h> header file. */ #define _GLIBCXX_HAVE_FENV_H 1 FreeBSD's (main) /usr/include/fenv.h is using code like: . . . #ifndef __fenv_static #define __fenv_static static #endif . . . __fenv_static __inline int feclearexcept(int __excepts) { fexcept_t __r; __mrs_fpsr(__r); __r &= ~__excepts; __msr_fpsr(__r); return (0); } . . . that disallows setting up the exports in C++ modules. FreeBSD has /usr/include/sys/cdefs.h : . . . #if defined(__STDC__) || defined(__cplusplus) . . . #if defined(__cplusplus) #define __inline inline /* convert to C++ keyword */ #else #if !(defined(__CC_SUPPORTS___INLINE)) #define __inline /* delete GCC keyword */ #endif /* ! __CC_SUPPORTS___INLINE */ #endif /* !__cplusplus */ #else /* !(__STDC__ || __cplusplus) */ . . . And FreeBSD has /usr/include/_ctype.h : . . . #include <sys/cdefs.h> . . . /* * _EXTERNALIZE_CTYPE_INLINES_ is defined in locale/nomacros.c to tell us * to generate code for extern versions of all our inline functions. */ #ifdef _EXTERNALIZE_CTYPE_INLINES_ #define _USE_CTYPE_INLINE_ #define static #define __inline #endif . . . There is also: /usr/include/arm/fenv.h : . . . #ifndef __fenv_static #define __fenv_static static #endif . . . #ifndef __ARM_PCS_VFP int feclearexcept(int __excepts); . . . #endif #else /* __ARM_PCS_VFP */ #define vmrs_fpscr(__r) __asm __volatile("vmrs %0, fpscr" : "=&r"(__r)) #define vmsr_fpscr(__r) __asm __volatile("vmsr fpscr, %0" : : "r"(__r)) #define _FPU_MASK_SHIFT 8 __fenv_static inline int feclearexcept(int __excepts) { fexcept_t __fpsr; vmrs_fpscr(__fpsr); __fpsr &= ~__excepts; vmsr_fpscr(__fpsr); return (0); } . . . Without __ARM_PCS_VFP involved, this would again end up blocking the C++ exports in std and in std.compat . It also does not use __inline but just inline. === Mark Millard marklmi at yahoo.com