C++ Logo


Advanced search

Re: [wg14/wg21 liaison] [isocpp-ext] Report from the recent C/C++ liaison meeting (SG22); includes new floating point types(!)

From: Jens Maurer <Jens.Maurer_at_[hidden]>
Date: Fri, 17 Sep 2021 23:28:09 +0200
On 17/09/2021 23.11, Jorg Brown via Ext wrote:
> On Fri, Sep 17, 2021 at 11:18 AM Joseph Myers <joseph_at_[hidden] <mailto:joseph_at_[hidden]>> wrote:
> On Fri, 17 Sep 2021, Jorg Brown via Liaison wrote:
> > Something that would make me incredibly happy is if c++23 said that I could
> > overload on std::float16, std::float32, std::float64, std::float80, and
> > std::float128, and that the basic functions (+-*/, abs, frexp, ldexp) all
> > work on those types, regardless of what the CPU natively supports.
> > Alternatively, if there were macros I could check that would tell me if
> > each of these had support - but it would still have to be guaranteed that
> > "float", "long", and "long double" could be passed to my overload, without
> > compile error.
> In C:
> * The types, where they exist, are always distinct, so _Float64, _Float32x
> and double are always different types, even if they have the same format.
> In C++ terms, that should mean you can overload on the types that exist
> without needing to be concerned about the possibility of two of them being
> the same.
> That's problematic, depending on the overload-resolution rules for the new floating-point types. Consider this overload set and a sample use:
> void Overload(const int8_t&);
> void Overload(const int16_t&);
> void Overload(const int32_t&);
> void Overload(const int64_t&);
> auto fn() {
> int i = 0;
> Overload(i);
> long l = 0;
> Overload(l);
> long long ll = 0;
> Overload(ll);
> }
> This causes an ambiguous overload error, because "long" is a distinct type from both "int" and "long long". See https://godbolt.org/z/YqYsvY94v <https://godbolt.org/z/YqYsvY94v>

Note that int8_t and friends are typedefs referring to built-in types,
so this technique causes trouble. For the new floating-point world,
there is no such problem, because _FloatN is guaranteed to be a new
fundamental type, different from any other _FloatN and different from
float, double, long double.

I think the situation above doesn't happen, or can be avoided by also
overloading on float, double, long double.

> * Any of the <float.h> macros can be used to check whether a type exists;
> you can use "#ifdef FLT16_MANT_DIG", after including <float.h> to see if
> _Float16 is supported, for example. (Note the special case in N2601 about
> non-arithmetic interchange format support: FLTN_DIG and FLTN_DECIMAL_DIG
> are defined there for if binaryN is supported by the encoding-conversion
> functions, even if the _FloatN type isn't supported.)
> Hmmm, good point... though of course for my purposes I'd want something that corresponded to std::float16, not necessarily _Float16.

The whole point of the present discussion is to make std::float16 identical
to _Float16, to permit writing interoperable code.

We can certainly make one dependent on the other.

> > Notably, the most glaring need for this is printf. If they are going to
> > introduce a pow that does the right thing, how about a type-generic
> In C, the strfrom functions (e.g. strfromf128) are provided for the new
> types, instead of having any corresponding printf format length modifiers.
> Likewise, strtof128 exists instead of any scanf support.
> Re: "strfromf128", is that documented anywhere? N1312 doesn't mention it and Google is surprisingly unhelpful... I presume it's just https://man7.org/linux/man-pages/man3/strfromd.3.html <https://man7.org/linux/man-pages/man3/strfromd.3.html> but with added types?

See WG14 N2601 section X.12.1.


Received on 2021-09-17 16:28:18