On Tue, 4 Aug 2026, 12:10 Tomasz Kaminski, <[email protected]> wrote:
> > > On Mon, Aug 3, 2026 at 6:58 PM Jonathan Wakely <[email protected]> wrote: > >> The <cerrno> header is freestanding in C++26. Since we don't have to be >> compatible with a C library or a kernel for freestanding, we can just >> define the error number macros to arbitrary values. >> >> We need to provide a consistent set of definitions whether <cerrno> or >> <errno.h> is included, and whether a freestanding header is included by >> using -ffreestanding with a full hosted installation, or with a >> non-hosted (i.e. --disable-hosted-libstdcxx) installation. We do not >> want a situation where including <errno.h> uses a system libc header and >> defines one set of values, but <cerrno> provides our own freestanding >> values. >> >> The approach taken here is to install our own copy of <errno.h> which >> does #include_next <errno.h> for hosted and which defines its own values >> for freestanding. Our <cerrno> will then find our own <errno.h> and so >> <cerrno> and <errno.h> will be consistent, and the macro values will >> always be the same for the freestanding headers. >> >> libstdc++-v3/ChangeLog: >> >> * include/Makefile.am (c_base_freestanding): Move cerrno to >> here from ... >> (c_base_headers): ... here. >> (c_compatibility_headers): Add errno.h. >> * include/Makefile.in: Regenerate. >> * include/c_compatibility/errno.h: Replace include <cerrno> with >> include_next <errno.h>. >> [!_GLIBCXX_HOSTED] (E2BIG,EACCES,EADDRINUSE,EADDRNOTAVAIL) >> (EAFNOSUPPORT,EAGAIN,EALREADY,EBADF,EBADMSG,EBUSY,ECANCELED) >> (ECHILD,ECONNABORTED,ECONNREFUSED,ECONNRESET,EDEADLK) >> (EDESTADDRREQ,EDOM,EEXIST,EFAULT,EFBIG,EHOSTUNREACH,EIDRM) >> (EILSEQ,EINPROGRESS,EINTR,EINVAL,EIO,EISCONN,EISDIR,ELOOP) >> (EMFILE,EMLINK,EMSGSIZE,ENAMETOOLONG,ENETDOWN,ENETRESET) >> (ENETUNREACH,ENFILE,ENOBUFS,ENODEV,ENOENT,ENOEXEC,ENOLCK) >> (ENOLINK,ENOMEM,ENOMSG,ENOPROTOOPT,ENOSPC,ENOSYS,ENOTCONN) >> (ENOTDIR,ENOTEMPTY,ENOTRECOVERABLE,ENOTSOCK,ENOTSUP,ENOTTY) >> (ENXIO,EOPNOTSUPP,EOVERFLOW,EOWNERDEAD,EPERM,EPIPE,EPROTO) >> (EPROTONOSUPPORT,EPROTOTYPE,ERANGE,EROFS,ESPIPE,ESRCH) >> (ETIMEDOUT,ETXTBSY,EWOULDBLOCK,EXDEV): Define. >> --- >> >> I don't really like this patch, but sending it for comment. >> >> Every time we add our own <name.h> C header it complicates things, and >> we have various bug reports (and patches) related to those files causing >> problems during bootstrap of obscure canadian-cross configurations. >> >> So I'm a bit concerned that adding <errno.h> just for Freestanding would >> end up causing regressions that affect Hosted builds too. >> > We are already conditionally installing more headers for Hosted builds, so > could we conditionally install the new header only for environments that > are > not hosted? This should avoid any potential impact on existing platforms. > That won't work, not consistently anyway. For freestanding, you can either build GCC with --disable-hosted-libstdcxx or you can build a hosted implementation but then use -ffreestanding. If we install different headers for the non-hosted build, you would not be able to include errno.h with -ffreestanding, or you would get the libc one which would have different error numbers. Maybe that's ok, and users would need to use a consistent "really freestanding" or "hosted but used as freestanding" installation. But I think it would be surprising. >> >> libstdc++-v3/include/Makefile.am | 3 +- >> libstdc++-v3/include/Makefile.in | 3 +- >> libstdc++-v3/include/c_compatibility/errno.h | 91 +++++++++++++++++++- >> 3 files changed, 94 insertions(+), 3 deletions(-) >> >> diff --git a/libstdc++-v3/include/Makefile.am >> b/libstdc++-v3/include/Makefile.am >> index 3c30aa21d6b5..18bb9f224563 100644 >> --- a/libstdc++-v3/include/Makefile.am >> +++ b/libstdc++-v3/include/Makefile.am >> @@ -902,6 +902,7 @@ endif >> c_base_srcdir = $(C_INCLUDE_DIR) >> c_base_builddir = . >> c_base_freestanding = \ >> + ${c_base_srcdir}/cerrno \ >> ${c_base_srcdir}/cfloat \ >> ${c_base_srcdir}/climits \ >> ${c_base_srcdir}/cstdalign \ >> @@ -919,7 +920,6 @@ c_base_headers = \ >> ${c_base_srcdir}/cassert \ >> ${c_base_srcdir}/ccomplex \ >> ${c_base_srcdir}/cctype \ >> - ${c_base_srcdir}/cerrno \ >> ${c_base_srcdir}/cfenv \ >> ${c_base_srcdir}/cinttypes \ >> ${c_base_srcdir}/ciso646 \ >> @@ -947,6 +947,7 @@ endif >> if GLIBCXX_C_HEADERS_C_GLOBAL >> c_compatibility_headers = \ >> ${c_compatibility_srcdir}/complex.h \ >> + ${c_compatibility_srcdir}/errno.h \ >> ${c_compatibility_srcdir}/fenv.h \ >> ${c_compatibility_srcdir}/tgmath.h \ >> ${c_compatibility_srcdir}/math.h \ >> diff --git a/libstdc++-v3/include/Makefile.in >> b/libstdc++-v3/include/Makefile.in >> index d081481293ff..feb6665ca401 100644 >> --- a/libstdc++-v3/include/Makefile.in >> +++ b/libstdc++-v3/include/Makefile.in >> @@ -1250,6 +1250,7 @@ experimental_bits_headers = \ >> c_base_srcdir = $(C_INCLUDE_DIR) >> c_base_builddir = . >> c_base_freestanding = \ >> + ${c_base_srcdir}/cerrno \ >> ${c_base_srcdir}/cfloat \ >> ${c_base_srcdir}/climits \ >> ${c_base_srcdir}/cstdalign \ >> @@ -1265,7 +1266,6 @@ c_base_freestanding = \ >> @GLIBCXX_HOSTED_TRUE@ ${c_base_srcdir}/cassert \ >> @GLIBCXX_HOSTED_TRUE@ ${c_base_srcdir}/ccomplex \ >> @GLIBCXX_HOSTED_TRUE@ ${c_base_srcdir}/cctype \ >> -@GLIBCXX_HOSTED_TRUE@ ${c_base_srcdir}/cerrno \ >> @GLIBCXX_HOSTED_TRUE@ ${c_base_srcdir}/cfenv \ >> @GLIBCXX_HOSTED_TRUE@ ${c_base_srcdir}/cinttypes \ >> @GLIBCXX_HOSTED_TRUE@ ${c_base_srcdir}/ciso646 \ >> @@ -1287,6 +1287,7 @@ c_compatibility_srcdir = >> ${glibcxx_srcdir}/include/c_compatibility >> c_compatibility_builddir = . >> @GLIBCXX_C_HEADERS_C_GLOBAL_TRUE@c_compatibility_headers = \ >> @GLIBCXX_C_HEADERS_C_GLOBAL_TRUE@ >> ${c_compatibility_srcdir}/complex.h \ >> +@GLIBCXX_C_HEADERS_C_GLOBAL_TRUE@ >> ${c_compatibility_srcdir}/errno.h \ >> @GLIBCXX_C_HEADERS_C_GLOBAL_TRUE@ ${c_compatibility_srcdir}/fenv.h >> \ >> @GLIBCXX_C_HEADERS_C_GLOBAL_TRUE@ >> ${c_compatibility_srcdir}/tgmath.h \ >> @GLIBCXX_C_HEADERS_C_GLOBAL_TRUE@ ${c_compatibility_srcdir}/math.h >> \ >> diff --git a/libstdc++-v3/include/c_compatibility/errno.h >> b/libstdc++-v3/include/c_compatibility/errno.h >> index 07e3c17e9173..3eea20e081bb 100644 >> --- a/libstdc++-v3/include/c_compatibility/errno.h >> +++ b/libstdc++-v3/include/c_compatibility/errno.h >> @@ -29,6 +29,95 @@ >> #ifndef _GLIBCXX_ERRNO_H >> #define _GLIBCXX_ERRNO_H 1 >> >> -#include <cerrno> >> +#include <bits/c++config.h> >> + >> +#if _GLIBCXX_HOSTED >> > Should whe use _has_include_next(<errno.h>)? So pull this header > if it is provided? > It's required for hosted implementations, and we know it's always present because everybody can already include it today. +#include_next <errno.h> >> +// Adhere to section 17.4.1.2 clause 5 of ISO 14882:1998 >> +#ifndef errno >> +#define errno errno >> +#endif >> + >> +#else >> +__thread inline int __errno_v = 0; >> + >> +#define errno __errno_v >> + >> +#define E2BIG 10007 >> +#define EACCES 10013 >> +#define EADDRINUSE 10098 >> +#define EADDRNOTAVAIL 10099 >> +#define EAFNOSUPPORT 10097 >> +#define EAGAIN 10011 >> +#define EALREADY 10114 >> +#define EBADF 10009 >> +#define EBADMSG 10074 >> +#define EBUSY 10016 >> +#define ECANCELED 10125 >> +#define ECHILD 10010 >> +#define ECONNABORTED 10103 >> +#define ECONNREFUSED 10111 >> +#define ECONNRESET 10104 >> +#define EDEADLK 10035 >> +#define EDESTADDRREQ 10089 >> +#define EDOM 10033 >> +#define EEXIST 10017 >> +#define EFAULT 10014 >> +#define EFBIG 10027 >> +#define EHOSTUNREACH 10113 >> +#define EIDRM 10043 >> +#define EILSEQ 10084 >> +#define EINPROGRESS 10115 >> +#define EINTR 10004 >> +#define EINVAL 10022 >> +#define EIO 10005 >> +#define EISCONN 10106 >> +#define EISDIR 10021 >> +#define ELOOP 10040 >> +#define EMFILE 10024 >> +#define EMLINK 10031 >> +#define EMSGSIZE 10090 >> +#define ENAMETOOLONG 10036 >> +#define ENETDOWN 10100 >> +#define ENETRESET 10102 >> +#define ENETUNREACH 10101 >> +#define ENFILE 10023 >> +#define ENOBUFS 10105 >> +#define ENODEV 10019 >> +#define ENOENT 10002 >> +#define ENOEXEC 10008 >> +#define ENOLCK 10037 >> +#define ENOLINK 10067 >> +#define ENOMEM 10012 >> +#define ENOMSG 10042 >> +#define ENOPROTOOPT 10092 >> +#define ENOSPC 10028 >> +#define ENOSYS 10038 >> +#define ENOTCONN 10107 >> +#define ENOTDIR 10020 >> +#define ENOTEMPTY 10039 >> +#define ENOTRECOVERABLE 10131 >> +#define ENOTSOCK 10088 >> +#define ENOTSUP 10095 >> +#define ENOTTY 10025 >> +#define ENXIO 10006 >> +#define EOPNOTSUPP 10095 >> +#define EOVERFLOW 10075 >> +#define EOWNERDEAD 10130 >> +#define EPERM 10001 >> +#define EPIPE 10032 >> +#define EPROTO 10071 >> +#define EPROTONOSUPPORT 10093 >> +#define EPROTOTYPE 10091 >> +#define ERANGE 10034 >> +#define EROFS 10030 >> +#define ESPIPE 10029 >> +#define ESRCH 10003 >> +#define ETIMEDOUT 10110 >> +#define ETXTBSY 10026 >> +#define EWOULDBLOCK 10011 >> +#define EXDEV 10018 >> + >> +#endif // HOSTED >> >> #endif >> -- >> 2.55.0 >> >>
