<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Joseph found a case that is not properly covered by the tgmath rules for functions that round to narrower type in the Part 3 annex (X.13 in N2601), namely the case where all arguments are of integer type and the macro prefix is dN for some N.<div class=""><br class=""></div><div class="">The problem exits because the first step of the type determination rules applies the usual arithmetic conversions which handle integer-type arguments based solely on argument types. This doesn’t work for functions that round to narrower type because the prefix might need to be considered too, as in the case of d32sqrt(n) which Joseph mentions below. (I had checked the rules against a matrix of possibilities with all possible prefixes and all possible floating types, but had assumed integer types were covered by the application of the usual arithmetic conversions.)</div><div class=""><br class=""></div><div class="">Here’s a way of addressing the problem ...</div><div class=""><br class=""></div><div class="">Change the first bullet in X.13 #5:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""> — First apply the rules (for determining the corresponding real type of the generic parameters) in 7.25 for macros that do not round result to narrower type, using the usual arithmetic conversion rules in X.4.2, to obtain a preliminary type P for the generic parameters.</div></blockquote><div class=""><br class=""></div><div class="">to:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""> — First, obtain a preliminary type P for the generic parameters: if all arguments are of integer type, then P is double if the macro prefix is  f, d, or dN for some N and P is _Decimal64 if the macro prefix is dN for some N; otherwise (if some argument is not of integer type), apply the rules (for determining the corresponding real type of the generic parameters) in 7.25 for macros that do not round result to narrower type, using the usual arithmetic conversion rules in X.4.2, to obtain P.</div></blockquote><div class=""><br class=""></div><div class="">This issue will be added to the agenda for the CFP September meeting.</div><div class=""><br class=""></div>- Jim Thomas<br class=""><div class=""><br class=""></div><div class=""><div><br class=""><blockquote type="cite" class=""><div class="">Begin forwarded message:</div><br class="Apple-interchange-newline"><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px;" class=""><span style="font-family: -webkit-system-font, Helvetica Neue, Helvetica, sans-serif; color:rgba(0, 0, 0, 1.0);" class=""><b class="">From: </b></span><span style="font-family: -webkit-system-font, Helvetica Neue, Helvetica, sans-serif;" class="">Joseph Myers <<a href="mailto:joseph@codesourcery.com" class="">joseph@codesourcery.com</a>><br class=""></span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px;" class=""><span style="font-family: -webkit-system-font, Helvetica Neue, Helvetica, sans-serif; color:rgba(0, 0, 0, 1.0);" class=""><b class="">Subject: </b></span><span style="font-family: -webkit-system-font, Helvetica Neue, Helvetica, sans-serif;" class=""><b class="">[SC22WG14.20399] tgmath.h narrowing macros with integer arguments</b><br class=""></span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px;" class=""><span style="font-family: -webkit-system-font, Helvetica Neue, Helvetica, sans-serif; color:rgba(0, 0, 0, 1.0);" class=""><b class="">Date: </b></span><span style="font-family: -webkit-system-font, Helvetica Neue, Helvetica, sans-serif;" class="">September 8, 2021 at 3:36:54 PM PDT<br class=""></span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px;" class=""><span style="font-family: -webkit-system-font, Helvetica Neue, Helvetica, sans-serif; color:rgba(0, 0, 0, 1.0);" class=""><b class="">To: </b></span><span style="font-family: -webkit-system-font, Helvetica Neue, Helvetica, sans-serif;" class=""><<a href="mailto:sc22wg14@open-std.org" class="">sc22wg14@open-std.org</a>><br class=""></span></div><br class=""><div class=""><div class="">The current C23 working draft defines the tgmath.h rules for narrowing <br class="">macros such as d32sqrt in a fairly ad hoc way that suffices for the types <br class="">in the main body of C23.<br class=""><br class="">N2601, the current version of TS 18661-3 as Annex, has somewhat more <br class="">complicated rules to account for the new types in that Annex (these rules <br class="">differ in various ways from those in the original TS, to account for <br class="">clarification requests reported against that TS and to work better when <br class="">such macros are used with e.g. _Float32_t arguments).<br class=""><br class="">Suppose you have<br class=""><br class="">int n;<br class=""><br class="">and call<br class=""><br class="">d32sqrt(n)<br class=""><br class="">which the main body of C23 would say calls the d32sqrtd64 function.  <br class="">Applying the Annex rules would seem to treat the integer argument as if it <br class="">had type double, so resulting in undefined behavior.<br class=""><br class="">For any case using only types and macros defined in the main body of the <br class="">standard, the Annex should not produce different results for which <br class="">function is chosen by an tgmath.h macro, and should not produce undefined <br class="">behavior for a case that is defined in the main body of the standard.<br class=""><br class="">Thus, if d32sqrt(n) is intended to be allowed, I think the Annex needs to <br class="">say something about the case of decimal narrowing macros with only integer <br class="">arguments, to avoid ending up with double being chosen as the preliminary <br class="">type P.<br class=""><br class="">A separate note on such macros with integer arguments: one example in <br class="">N2601 says that f32xsqrt(n) resolves to call f32xsqrtf64.  As I read <br class="">N2601, n is regarded as having type double, P is double, and if _Float64x <br class="">exists then f32xsqrtf64x is called.  (f32xsqrtf64 would have been correct <br class="">with the resolution to FPE CR#13.  If the change between that resolution <br class="">and C23 is as intended, then the example needs updating.)<br class=""><br class="">-- <br class="">Joseph S. Myers<br class=""><a href="mailto:joseph@codesourcery.com" class="">joseph@codesourcery.com</a><br class=""></div></div></blockquote></div><br class=""></div></body></html>