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