3954. Feature-test macros in C headers (<stddef.h> etc.)

Section: 17.14.1 [support.c.headers.general] Status: New Submitter: Jiang An Opened: 2023-07-06 Last modified: 2024-02-22

Priority: 3

View all issues with New status.

Discussion:

Several feature-test macros are available in C++ versions of C headers (e.g. __cpp_lib_byte is available in <cstddef>). However, the current standard wording doesn't seem to make the distinction between C++ library feature-test macros and macros from C, so it's not very clear that whether <stddef.h> and its friends are required to provide __cpp_lib_* macros in C++.

Presumably, name.h should provide macros shown in the synopsis of its corresponding cname (as required in C), but should not be required to provide C++ library feature-test macros because such requirement would generally require implementations of the C standard library to change. I think we should make clarification in 17.14.1 [support.c.headers.general].

[2024-02-22; Reflector poll]

Set priority to 3 after reflector poll in July 2023.

[Jonathan commented]

The issue says that "such requirement would generally require implementations of the C standard library to change" but this is not true. A conforming C++ library already needs a C++-aware <stdlib.h> and <math.h>, and has done so since C++98! We should be cautious about expanding the set of C headers that need to be C++-aware, but if we require <stdlib.h> to define these functions:


constexpr long abs(long);
constexpr long long abs(long long);
then it can also define __cpp_lib_constexpr_math.

We have these <cxxx> headers providing feature test macros:

<cmath>:
__cpp_lib_constexpr_cmath
 __cpp_lib_hypot
__cpp_lib_interpolate
__cpp_lib_math_special_functions

<cstddef>:
__cpp_lib_byte

<cstdlib>:
__cpp_lib_constexpr_cmath

For <stdlib.h> and <math.h> the implementation already needs a C++-specific version of the header, because ::abs is required to be overloaded (and constexpr) in <stdlib.h> and <math.h> (and all the math functions have to be constexpr even if you include <math.h>). So I see no issue here: the <xxx.h> headers should obviously define the same macros as the <cxxx> headers.

We do not require ::byte to be in <stddef.h>, so maybe we should not require the macro there either. Except that std::byte is permitted to be in <stddef.h>, just not in the global namespace (see LWG 3883). So maybe SD-6 should simply clarify that the macro indicates the presence of std::byte, not ::byte, and whether std::byte and its macro are defined by <stddef.h> is unspecified. Also related to LWG 3484.

[Jens commented]

It seems 17.14 [support.c.headers] is silent on which macros from the <cxxx> headers are made available via the <xxx.h> headers, given that 17.14.7 [support.c.headers.other] talks about names placed in the standard library namespace (macros don't fit that description).

[Ben noted some additional macros]


#define __cpp_lib_freestanding_cstdlib      new-val // freestanding, also in <cstdlib>, <cmath>
#define __cpp_lib_freestanding_cstring      new-val // freestanding, also in <cstring>
#define __cpp_lib_freestanding_cwchar       new-val // freestanding, also in <cwchar>
#define __cpp_lib_freestanding_errc         new-val // freestanding, also in <cerrno>, <system_error>

Proposed resolution: