Suppose we have a system where double, long double, and _Float64 or std::float64_t all use the same underlying floating-point semantics. Under C23 (taken from draft N3096), the common real floating-point type is determined by first using the interchange type (i.e., _Float64), then long double, and then double). Under C++23, [conv.rank] specifies that long double and double are different ranks (per p2.2), with std::float64_t is in the same rank as double (per p2.5) and a higher subrank than double (per 3).
Under C's rules, then, if you were to add long double and _Float64, the _Float64 would be the result. But under C++, long double is the result, because the long double rank wins out over _Float64's rank. It is not clear that this result was intentional. P1467R6 and later revisions all have a C compatibility section, where these paragraphs appear:
Previously, there was also a difference in usual arithmetic conversions. This proposal and C have always agreed on the results of a binary operator when at least one of the operands is a floating-point type and the two types have different representations. However, when the two operands were different floating-point types with the same representation, this paper proposed that double + std::float64_t (assuming they have the same representation) would have type double, while in C, double + _Float64 has type _Float64. The rationale for the C rules is that if a user buys into the fixed-layout types explicitly, we should preserve that decision through expressions and library function calls.
This matter was discussed during an SG22 meeting, and a consensus was reached that this paper should instead adopt the C rules; now, with this revision, the result of double + std::float64_t is std::float64_t.
A subsequent followup to the CFP mailing list by the author of P1467 was sent to ask about this case, and if C would change its rules to make long double + _Float64 yield long double instead here: http://mailman.oakapple.net/pipermail/cfp-interest/2021-October/002256.html. The CFP reply indicated no desire in C to change, and the subsequent CFP telecon also affirmed that (see https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2876.pdf for meeting minutes). However, none of the further discussions of the paper in C++ appear to have observed this incompatibility with C, although the topic of mapping to double or long double was discussed during CWG telecons (specifically the one on 2022-03-25).
It is not clear if the incompatibility between C and C++ with regards to the arithmetic conversions here was intentional.
Suggested resolution:
Change [conv.rank]p2.5 to
An extended floating-point type with the same set of values as more than one cv-unqualified standard floating-point type has a rank equal to the highest rank among such types.
Full name of submitter: Joshua Cranmer
Reference (section label): [conv.rank]
Issue description:
Suppose we have a system where
double
,long double
, and_Float64
orstd::float64_t
all use the same underlying floating-point semantics. Under C23 (taken from draft N3096), the common real floating-point type is determined by first using the interchange type (i.e.,_Float64
), thenlong double
, and thendouble
). Under C++23, [conv.rank] specifies thatlong double
anddouble
are different ranks (per p2.2), withstd::float64_t
is in the same rank asdouble
(per p2.5) and a higher subrank than double (per 3).Under C's rules, then, if you were to add
long double
and_Float64
, the_Float64
would be the result. But under C++,long double
is the result, because thelong double
rank wins out over_Float64
's rank. It is not clear that this result was intentional. P1467R6 and later revisions all have a C compatibility section, where these paragraphs appear:Records of the relevant SG22 meeting can be found at https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2835.pdf, which confirm that this is accurate.
A subsequent followup to the CFP mailing list by the author of P1467 was sent to ask about this case, and if C would change its rules to make
long double
+_Float64
yieldlong double
instead here: http://mailman.oakapple.net/pipermail/cfp-interest/2021-October/002256.html. The CFP reply indicated no desire in C to change, and the subsequent CFP telecon also affirmed that (see https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2876.pdf for meeting minutes). However, none of the further discussions of the paper in C++ appear to have observed this incompatibility with C, although the topic of mapping todouble
orlong double
was discussed during CWG telecons (specifically the one on 2022-03-25).It is not clear if the incompatibility between C and C++ with regards to the arithmetic conversions here was intentional.
Suggested resolution: Change [conv.rank]p2.5 to