<p>This is an update for N2823 as requested by WG14 in the 2021/11 meeting.</p>
<p>All changes requested by WG14 were made. They include: More text for motivation and rationale, removal of what was voted in already, and addition of relative diffs (from/to aspects of the suggested changes to the standard).</p>
<p><strong>1. Motivation</strong></p>
<p>Some members of the WG21 committee seem to be concerned with the expansion in scope in freestanding environments in C23 due to the changes brought in from the integration of TS 18661. This paper tries to address the concerns brought forward in WG14 reflector messages 19444 and 19445.</p>
<p>In particular, bringing in more thread local storage via the errno variable and bringing in locales through the string to numeric value functions. The addition of thread local storage is a problem in general since freestanding applications often do not want to have "global" storage overhead or cannot have it. Locales have a similar issue in that most freestanding applications do not deal with locales (and hence the associated storage needed for them).</p>
<p>The general floating-point environment (described in 7.6) also has thread storage duration and hence requires overhead in terms of "global" storage. This was not directly mentioned in the reflector messages but is a conceivable concern that needs to be addressed.</p>
<p><strong>2. Description</strong></p>
<p>Two alternatives are proposed to try and alleviate the concerns given above. The first one is intended to reduce the scope of changes brought in by the TS to remove requirements for thread local storage (errno) and modification to "global" state (the floating-point environment, which also has thread storage duration), and does so in a general way.</p>
<p>The second alternative (which can be done in conjunction with the first alternative if requested by WG14) is to let implementations choose between having errno or modifying the floating point exception states, or both where possible, and does so by modifying functions that currently require only errno to be set. Note that the second alternative does not remove the need to modify the floating-point environment in cases outside certain functions. For example, setting and clearing floating-point exception flags are required.</p>
<p>For alternative 1: The practical set of functions in the <strong>fenv.h</strong> header seem to be only <strong>fegetround</strong> and <strong>fe_dec_getround</strong>, but the other query functions were listed as well since they do not modify the floating-point environment. The reduced list of functions to be only <strong>fegetround</strong> and <strong>fe_dec_getround</strong> is a possible modification to alternative 1, if chosen.</p>
<p><strong>3. Suggested changes</strong></p>
<p><strong><em>Alternative 1</em></strong>: In N2596, change Section 4#7 from:</p>
<p style="padding-left: 30px;">The strictly conforming programs that shall be accepted by a conforming freestanding implementation that defines __STDC_IEC_60559_BFP__ or __STDC_IEC_60559_DFP__ may also use features in the contents of the standard headers <fenv.h> and <math.h> and the numeric conversion functions (7.22.1) of the standard header <stdlib.h>. All identifiers that are reserved when <stdlib.h> is included in a hosted implementation are reserved when it is included in a freestanding implementation.</p>
<p>to (exclusion version):</p>
<p style="padding-left: 30px;">The strictly conforming programs that shall be accepted by a conforming freestanding implementation that defines __STDC_IEC_60559_BFP__ or __STDC_IEC_60559_DFP__ may also use features<span style="color: #339966;">, without the requirements to set errno (see 7.5) or modify the floating-point environment (see 7.6), in the following:<br /></span><span style="color: #339966;">- all the macros and the following functions in</span> <fenv.h><span style="color: #339966;">: fegetexceptflag, fetestexceptflag, fetestexcept, fegetmode, fegetround, fe_dec_getround, fegetenv</span><br /><span style="color: #339966;"> - </span><math.h><br /> <span style="color: #339966;">- the floating-point numeric conversion functions (7.22.1) of the standard header <stdlib.h>: strtod, strtof, strtold, strtod32, strtod64, strtod128</span><br /> All identifiers that are reserved when <stdlib.h><span style="color: #339966;"> and <fenv.h> are</span> included in a hosted implementation are reserved when it is included in a freestanding implementation.</p>
<p>  In 7.22.1, insert before paragraph 1:</p>
<p style="padding-left: 30px;"><span style="color: #339966;">For freestanding implementations, neither errno or the FP exception flags need be affected by any of the functions in this clause; in addition, locales need not have any affect on these functions.</span></p>
<p>Or (inclusive version):</p>
<p style="padding-left: 30px;">The strictly conforming programs that shall be accepted by a conforming freestanding implementation that defines __STDC_IEC_60559_BFP__ or __STDC_IEC_60559_DFP__ may also use features in the contents of the standard header <span style="color: #339966;"><math.h><sup>[?]</sup>, the macros and rounding mode query functions</span> in the standard header <fenv.h> and the <span style="color: #339966;">strto*</span> numeric conversion functions (7.22.1) of the standard header <stdlib.h>. All identifiers that are reserved when <stdlib.h><span style="color: #339966;">, <fenv.h> and <math.h> are</span> included in a hosted implementation are reserved when it is included in a freestanding implementation.</p>
<p style="padding-left: 30px;"><span style="color: #339966;">[?] Even though the specification of functions in math.h requires errno to be set, since errno.h is not required, the “as if” rule permits not reporting any errors, alleviating the need for actual thread local storage for errno. Similarly this applies for the floating-point environment.</span></p>
<p><br /> <em><strong>Independent addition/Alternative 2</strong></em>: In N2596 change the strto{d,f,ld} functions in 7.22.1.5#10 from:</p>
<p style="padding-left: 30px;">The functions return the converted value, if any. If no conversion could be performed, zero is returned. If the correct value overflows and default rounding is in effect (7.12.1), plus or minus HUGE_VAL, HUGE_VALF, or HUGE_VALL is returned (according to the return type and sign of the value), and the value of the macro ERANGE is stored in errno. If the result underflows (7.12.1), the functions return a value whose magnitude is no greater than the smallest normalized positive number in the return type; whether errno acquires the value ERANGE is implementation-defined.</p>
<p>to:</p>
<p style="padding-left: 30px;">The functions return the converted value, if any. If no conversion could be performed, zero is returned.</p>
<p style="padding-left: 30px;">If the correct value overflows and default rounding is in effect (7.12.1), plus or minus HUGE_VAL, HUGE_VALF, or HUGE_VALL is returned (according to the return type and sign of the value); the value of the macro ERANGE is stored in errno <span style="color: #339966;">if the integer expression <strong>math_errhandling & MATH_ERRNO</strong> is nonzero; and the "overflow" floating-point exception is raised if the integer expression <strong>math_errhandling & MATH_ERREXCEPT</strong> is nonzero.</span></p>
<p style="padding-left: 30px;">If the result underflows (7.12.1), the functions return a value whose magnitude is no greater than the smallest normalized positive number in the return type; whether errno acquires the value ERANGE <span style="color: #339966;">if the integer expression <strong>math_errhandling & MATH_ERRNO</strong> is nonzero</span> is implementation defined<span style="color: #339966;">; and if the integer expression <strong>math_errhandling & MATH_ERREXCEPT</strong> is nonzero, whether the "underflow" floating-point exception is raised is implementation-defined.</span></p>
<p>For the analogous wide character functions:</p>
<p>Change 7.29.4.1.1#10 from:</p>
<p style="padding-left: 30px;">The functions return the converted value, if any. If no conversion could be performed, zero is returned. If the correct value overflows and default rounding is in effect (7.12.1), plus or minus <strong>HUGE</strong><strong>_</strong><strong>VAL</strong>, <strong>HUGE</strong><strong>_</strong><strong>VALF</strong>, or <strong>HUGE</strong><strong>_</strong><strong>VALL </strong>is returned (according to the return type and sign of the value), and the value of the macro <strong>ERANGE </strong>is stored in <strong>errno</strong>. If the result underflows (7.12.1), the functions return a value whose magnitude is no greater than the smallest normalized positive number in the return type; whether <strong>errno </strong>acquires the value <strong>ERANGE </strong>is implementation-defined.</p>
<p>to:</p>
<p style="padding-left: 30px;">The functions return the converted value, if any. If no conversion could be performed, zero is returned.</p>
<p style="padding-left: 30px;">If the correct value overflows and default rounding is in effect (7.12.1), plus or minus <strong>HUGE</strong><strong>_</strong><strong>VAL</strong>, <strong>HUGE</strong><strong>_</strong><strong>VALF</strong>, or <strong>HUGE</strong><strong>_</strong><strong>VALL </strong>is returned (according to the return type and sign of the value), and the value of the macro <strong>ERANGE </strong>is stored in <strong>errno</strong> <span style="color: #339966;">if the integer expression <strong>math_errhandling & MATH_ERRNO</strong> is nonzero; and the "overflow" floating-point exception is raised if the integer expression <strong>math_errhandling & MATH_ERREXCEPT</strong> is nonzero.</span></p>
<p style="padding-left: 30px;">If the result underflows (7.12.1), the functions return a value whose magnitude is no greater than the smallest normalized positive number in the return type; whether <strong>errno </strong>acquires the value <strong>ERANGE</strong><span style="color: #339966;"> if the integer expression <strong>math_errhandling & MATH_ERRNO</strong> is nonzero is implementation defined; if the integer expression <strong>math_errhandling & MATH_ERREXCEPT</strong> is nonzero, whether the "underflow" floating-point exception is raised</span> is implementation-defined.</p>
<p>Change 4#7 as follows from:</p>
<p style="padding-left: 30px;">The strictly conforming programs that shall be accepted by a conforming freestanding implementation that defines __STDC_IEC_60559_BFP__ or __STDC_IEC_60559_DFP__ may also use features in the contents of the standard headers <fenv.h> and and <math.h> and the numeric conversion functions (7.22.1) of the standard header <stdlib.h>. All identifiers that are reserved when <stdlib.h> is included in a hosted implementation are reserved when it is included in a freestanding implementation.</p>
<p>to:</p>
<p style="padding-left: 30px;">The strictly conforming programs that shall be accepted by a conforming freestanding implementation that defines __STDC_IEC_60559_BFP__ or __STDC_IEC_60559_DFP__ may also use features in the contents of the standard headers <fenv.h> and <math.h> and the <span style="color: #339966;">strto* f</span><span style="color: #339966;">loating-point</span> numeric conversion functions (7.22.1) of the standard header <stdlib.h>. All identifiers that are reserved when <stdlib.h> is included in a hosted implementation are reserved when it is included in a freestanding implementation.</p>