Issue 1074: Feature test macros and freestanding

Authors: Jay Ghiron
Date: 2026-06-04
Submitted against: C23
Status: Open

The strictly conforming programs that shall be accepted by a conforming freestanding implementation that defines __STDC_IEC_60559_BFP__ or __STDC_IEC_60559_DFP__ can also use features in the contents of the standard headers <fenv.h>, <math.h>, and the strto* floating-point numeric conversion functions (7.24.2) of the standard header <stdlib.h>, provided the program does not set the state of the FENV_ACCESS pragma to "on".

(C23 4 "Conformance" paragraph 8.)

This text is here so that freestanding implementations that define either __STDC_IEC_60559_BFP__ or __STDC_IEC_60559_DFP__ must provide library features associated with those feature test macros. However, many of the other feature test macros do not have similar wording. __STDC_IEC_60559_TYPES__ can only be defined if __STDC_IEC_60559_BFP__ is defined, __STDC_IEC_60559_DFP__ is defined, or both are defined so this text will also apply.

Question 1

If a freestanding implementation does not define __STDC_NO_COMPLEX__, is it only necessary for the types to be supported but not the header <complex.h>? If __STDC_IEC_60559_COMPLEX__ is defined in addition to __STDC_NO_COMPLEX__ not being defined, is it still not necessary for a freestanding implementation to provide <complex.h>?

Question 2

If a freestanding implementation defines __STDC_LIB_EXT1__, is it only necessary to support rsize_t in <stddef.h> and <string.h> (but not in <stdio.h>, <time.h>, or even <stdlib.h>), RSIZE_MAX in <stdint.h>, and the additional functions in <string.h>? Notably, it appears that strerror_s and strerrorlen_s would require support despite strerror not needing to be supported because it depends upon the locale.

Question 3

If a freestanding implementation does not define __STDC_NO_ATOMICS__, is it only necessary for atomic types to be supported but not the header <stdatomic.h>? If so, what would memory_order_seq_cst semantics on loads and stores mean without <stdatomic.h> being provided?

Question 4

If a freestanding implementation does not define __STDC_NO_THREADS__, does that impose no requirements?

Under a hosted implementation that does not define __STDC_NO_THREADS__, a program can have more than one thread of execution (or thread) running concurrently.

(C23 5.2.2.5 "Multi-threaded executions and data races" paragraph 1.)

It seems like freestanding with multithreading is simply not a possibility acknowledged by the standard. Note that <threads.h> includes <time.h>, which freestanding implementations also do not need to support.

Question 5

If <tgmath.h> is included on a hosted implementation while __STDC_NO_COMPLEX__ is defined, what happens?

The header includes the headers <math.h> and <complex.h> and defines several type-generic macros.

(C23 7.27 "Type-generic math <tgmath.h>" paragraph 1.)

<complex.h> might not be provided, so might it be invalid to include <tgmath.h>? Note that freestanding implementations which define __STDC_IEC_60559_BFP__ or __STDC_IEC_60559_DFP__ do not need to provide <tgmath.h>, even though <math.h> is required to be provided.

Question 6

provided the program does not set the state of the FENV_ACCESS pragma to "on"

(C23 4 "Conformance" paragraph 8.)

Does setting the FENV_ACCESS pragma to "default" when the default is "on" get considered the same as setting the FENV_ACCESS pragma to "on"? If so, would the default FENV_ACCESS pragma being "on" at the start be considered the same as setting the FENV_ACCESS pragma to "on"?

If the FENV_ACCESS pragma was set to "on", would it preclude using the previously specified features only while it is set to "on" or would it being set to "on" once preclude using the previously specified features for the whole translation unit?