Date: Fri, 17 Sep 2021 14:11:16 -0700
On Fri, Sep 17, 2021 at 11:18 AM Joseph Myers <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
* 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.
> > Looking at the actual details of
> > http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1312.pdf , I find one
> > thing new and intriguing: "Type-generic macros". Specifically, it says
> > that if you include <tgmath.h>, you can write "pow(2, 3.0)" and get the
> > double version of pow, and you can write "pow(2, 3.0DD)" and get the
> > _Decimal64 version. This is of course common practice in C++, but how
> does
> > C do this without overloads?
>
> C11 and later provide _Generic to allow users to write that sort of macro
> themselves (before, it could be done using implementation extensions;
> tgmath.h was added in C99).
>
Thanks, wow I'm out of date about some parts of C. :-(
> > 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 but with added types?
-- Jorg
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
* 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.
> > Looking at the actual details of
> > http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1312.pdf , I find one
> > thing new and intriguing: "Type-generic macros". Specifically, it says
> > that if you include <tgmath.h>, you can write "pow(2, 3.0)" and get the
> > double version of pow, and you can write "pow(2, 3.0DD)" and get the
> > _Decimal64 version. This is of course common practice in C++, but how
> does
> > C do this without overloads?
>
> C11 and later provide _Generic to allow users to write that sort of macro
> themselves (before, it could be done using implementation extensions;
> tgmath.h was added in C99).
>
Thanks, wow I'm out of date about some parts of C. :-(
> > 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 but with added types?
-- Jorg
Received on 2021-09-17 16:11:31