[PATCH][RFC] libstdc++ Provide <cerrno> and <errno.h> for freestanding
Tomasz Kaminski
tkaminsk@redhat.com
Wed Aug 5 06:43:14 GMT 2026
On Tue, Aug 4, 2026 at 6:01 PM Jonathan Wakely <jwakely.gcc@gmail.com>
wrote:
>
>
> On Tue, 4 Aug 2026, 12:10 Tomasz Kaminski, <tkaminsk@redhat.com> wrote:
>
>>
>>
>> On Mon, Aug 3, 2026 at 6:58 PM Jonathan Wakely <jwakely@redhat.com>
>> 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.
>
That where my suggestion for using has_include_next where comming from. If
you build with
--disable-hosted-libstdcxx you will get system errno.h regardless if you
use -ffreestanding or not.
And if you enable --disable-hosted-libstdcxx then you get a errno.h file
installed, that will
use __has_include_next and also pull libc errno.h file on the same target.
So result
will be consistent.
And errno.h does not really have operating system dependencies, so I assume
it could
exist on some freenstanding enviroments, and provide some system specific
constants.
>
>
>>>
>>> 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
>>>
>>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20260805/10668b3d/attachment-0001.htm>
More information about the Libstdc++
mailing list