<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body style="overflow-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div>This note follows up on the action item</div><div><br></div><div>    Jim & Jerome: Investigate Joseph Meyers's issue of the conflicting requirements for double_t to be either double or long double.</div><div><br></div><div>Joseph’s message (at the end of this one) describes contradictory specification for double_t: when double and long double formats are the same and FLT_EVAL_METHOD is 2, the main standard says double_t is defined to be long double, but Annex H implies double_t is defined to be double. The relevant sections are:</div><div><br></div><div>7.12.1 #3</div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><div>... if FLT_EVAL_METHOD equals 2, they [referring to float_t and double_t] are both long double; ...</div></blockquote><div><br></div><div>and</div><div><br></div><div>H.11.1 #6</div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><div>If FLT_RADIX is 2 and FLT_EVAL_METHOD (H.3) is nonnegative, then each of the types [referring to the _t types] corresponding to a standard or binary floating type is the type whose range and precision are specified by FLT_EVAL_METHOD to be used for evaluating operations and literals of that standard or binary floating type. </div></blockquote><div><br></div><div>which refers to</div><div><br></div><div>H.3 #2</div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><div>[if FLT_EVAL_METHOD is 2] evaluate operations and literals, whose semantic type comprises a set of values that is a strict subset of the values of long double, to the range and precision of long double; evaluate all other operations and literals to the range and precision of the semantic type;</div></blockquote><div><br></div><div>Thus if double and long double have the same values, Annex H specifies double_t to be double, contradicting 7.12.1 #3.</div><div><br></div><div>The previous wording in TS-3 (the base document for Annex H), referred to in the Note at the end of Joseph’s message, is</div><div><br></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><div>[if FLT_EVAL_METHOD is 2] evaluate operations and constants, whose semantic type has at most the range and precision of long double, to the range and precision of long double; ...</div></blockquote><div><br></div><div>If double and long double have the same values, double has (at most) the range and precision of long double. Thus TS-3 specifies double_t to be long double, which is consistent with 7.12.1 #3.</div><div><br></div><div>Going from TS-3 to Annex H, we effectively changed the criterion for evaluating to the special evaluation type determined by FLT_EVAL_METHOD (instead of to the semantic type): </div><div><br></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><div>TS-3 says use the special evaluation type if the values of the semantic type are a subset of (or equivalent to) the values of the evaluation type.</div><div><br></div><div>Annex H says use the special evaluation type if the values of the semantic type are a strict (proper) subset of the values of the evaluation type.</div></blockquote><div><br></div><div>The only cases affected by the change are where the semantic type of the operation has the same format as the special evaluation type. </div><div><br></div><div>The _t types are the types FLT_EVAL_METHOD specifies to be used for evaluating operations of the semantic type, so they were affected by the change. Thus the conflict.</div><div><br></div><div>We believe the change was made without awareness of this problem. Discussion of rationale for the change is at the end.</div><div><br></div><div><br></div><div><b style="font-size: 14px;">Options for addressing the conflict</b></div><div><br></div><div>1. In Annex H, change the FLT_EVAL_METHOD specification to be effectively equivalent to TS-3. </div><div><br></div><div>2. In Annex H, keep the general specification for FLT_EVAL_METHOD but treat the case of double and long double having the same format specially to match 7.12.1 #3.</div><div><br></div><div>3. In the main standard, disallow FLT_EVAL_METHOD = 2 if double and long double have the same format and Annex H is supported.</div><div><br></div><div>We recommend option 1. It makes Annex H a natural extension of the main body of the standard in that it continues the practice of using the special evaluation format whenever its values include all the values of the semantic type. It requires implementations that support C23 Annex H to change _t types in some cases; however, we expect the impact to be low, because Annex H (with the problematic change from TS-3) was just introduced in C23 and because users would be very unlikely to be affected because evaluation formats are not changed.</div><div><br></div><div>Options 2 and 3, except for the one problematic case, preserve the change from TS-3 to Annex H, which changed the general criterion for using the special evaluation format. Arguments for the change (see discussion of rationale below) are speculative: there is no actual evidence to support them.</div><div><br></div><div>Options 2 and 3 entail adding special cases, further complicating the specification.</div><div><br></div><div>Option 2 could affect implementations though only if they manifested the incompatibility. </div><div><br></div><div>Option 3 could affect implementations that attempted to do what option 3 would disallow.</div><div><br></div><div><br></div><div><b style="font-size: 14px;">Discussion of rationale for the change (from TS-3 to Annex H)</b></div><div><br></div><div>Why did we make the change? This CFP paper provides some background:</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">       </span>https://cfp-wiki.esi.com.au/pub/CFP/WebHome/Example_for_FLT_EVAL_METHOD-20190815.pdf</div><div><br></div><div>Explicit use of a type might be expected to result in that type, unless the evaluation format is actually wider. E.g. if FLT_EVAL_METHOD is 0, one might expect (_Float32)x + (_Float32)y to have type _Float32 instead of float. A counter perspective, reflecting the historical hardware origins of wide evaluation, is that an evaluation type given by the evaluation method is expected to be effective unless the semantic type is actually wider. Since Annex F requires both _Float32 and float to have the same format and arithmetic, the result value and side effects are the same regardless of the evaluation type. However, the definition of _Float32_t, which gives the evaluation type, is affected: _Float32 vs float. </div><div><br></div><div>An implementation that uses ISO/IEC 60559 formats for its types but that does not have strict 60559 arithmetic might consider adding 60559 arithmetic for extension types like in Annex H. For this purpose, explicit use of a 60559 type should result in 60559 arithmetic, not be changed to the old non 60559 arithmetic because the values are not a strict subset. Note that this sort of implementation couldn’t actually conform to Annex H because Annex H requires float and double to be 60559 types, and we are not aware of any expressed interest in supporting it.</div><div><br></div><div>- Jim and Jerome</div><div><br></div><div><br></div><div><b style="font-size: 14px;">Joseph’s message</b></div><div><br></div><div>From: Joseph Myers <josmyers@redhat.com></div><div>Subject: [SC22WG14.34201] FLT_EVAL_METHOD, double_t and Annex H</div><div>Date: October 24, 2025 at 3:27:05 PM PDT</div><div>To: sc22wg14@open-std.org</div><div><br></div><div>Suppose FLT_EVAL_METHOD is 2 and long double has the same set of values as </div><div>double.</div><div><br></div><div>According to the main standard, FLT_EVAL_METHOD == 2 means that double_t </div><div>is defined as long double.</div><div><br></div><div>According to Annex H, FLT_EVAL_METHOD == 2 means "evaluate operations and </div><div>literals, whose semantic type comprises a set of values that is a strict </div><div>subset of the values of long double, to the range and precision of long </div><div>double; evaluate all other operations and literals to the range and </div><div>precision of the semantic type", and "If FLT_RADIX is 2 and </div><div>FLT_EVAL_METHOD (H.3) is nonnegative, then each of the types corresponding </div><div>to a standard or binary floating type is the type whose range and </div><div>precision are specified by FLT_EVAL_METHOD to be used for evaluating </div><div>operations and literals of that standard or binary floating type.".</div><div><br></div><div>Does that wording apply to double_t as well as to the other *_t defined in </div><div>Annex H?  If so, because the values of double aren't a *strict* subset of </div><div>those of double, "the type whose range and precision are specified by </div><div>FLT_EVAL_METHOD to be used for evaluating operations and literals of that </div><div>standard or binary floating type" would, in the case of double_t, be </div><div>double not long double, and that would indicate that double_t should be </div><div>defined as double (although float_t and long_double_t would be long </div><div>double).  Does that mean that Annex H does not permit FLT_EVAL_METHOD == 2 </div><div>when long double and double have the same set of values, because of that </div><div>contradiction in how to define double_t?</div><div><br></div><div>(Note: the "strict subset" in how FLT_EVAL_METHOD is defined in Annex H is </div><div>a change relative to TS 18661-3 which instead talked about "at most </div><div>the range and precision".  I don't know the reason for that change, which </div><div>affects the definition of the *_t types for types with the same set of </div><div>values as the type implied by FLT_EVAL_METHOD - for example, if </div><div>FLT_EVAL_METHOD is 2, it affects double_t if double has the same set of </div><div>values as long double, _Float64_t if _Float64 does, and so on.)</div><div><br></div><div>-- </div><div>Joseph S. Myers</div><div>josmyers@redhat.com</div></body></html>