Date: Tue, 26 Aug 2025 15:22:33 -0400
On 8/25/25 2:36 PM, Tiago Freire via Std-Proposals wrote:
> I personally don't see how in most commonly used platforms (x86_64, ARM, etc..)std::float32_t andstd::float64_t would be anything other than an alias to float and double, no conversion necessary.
> If they have same bitwise representation and requirements, then I assume that yes you could just reinterpret_cast between them, that's what reinterpret_cast is for. But then again, probably unnecessary as I assume they will just be aliases of the thing you already wanted so casting is unnecessary.
No, that isn't what reinterpret_cast is for. reinterpret_cast allows for
the construction of a pointer or reference of a type that corresponds to
the actual type of the object at the provided location. It can't be used
for type punning except in certain cases involving non-aliasing types.
>
> -----Original Message-----
> From: Std-Proposals<std-proposals-bounces_at_[hidden]> On Behalf Of Paul Caprioli via Std-Proposals
> Sent: Monday, August 25, 2025 20:26
> To:std-proposals_at_[hidden]
> Cc: Paul Caprioli<paul_at_[hidden]>
> Subject: Re: [std-proposals] TBAA and extended floating-point types
>
> IEEE 754-2019 defines floating-point formats.
> All formats can be supported as arithmetic formats; that is, they may be used to represent floating-point operands or results.
> Specific fixed-width encodings for binary and decimal formats are defined for a subset of the formats.
> These interchange formats are identified by their size and can be used for the exchange of floating-point data between implementations.
>
> I assumestd::float16_t is a C++ arithmetic format.
> Note that it is unrelated to Unicode. See:https://en.wikipedia.org/wiki/UTF-16
>
> The C++ standard section [basic.extended.fp] does not make clear (to me at least) the intended purpose ofstd::float32_t andstd::float64_t.
> In particular, interoperability with arrays of float and double seems awkward at best.
>
> I'm requesting feedback as to whether reinterpret_cast should be made to work between floating-point types having identical representations.
> Should I bother to author such a proposal or would I be wasting my time?
I think you would either have to propose that such types do alias (in
which case no changes to reinterpret_cast would be needed) or you need
to come up with a more novel solution, perhaps something similar to what
is explored in P2626 <https://wg21.link/p2626>.
Consider:
void f(std::float64_t *pf64) {
*pf64 = 2.0;
}
double g(double *pd) {
std::float64_t *pf64 = reinterpret_cast<std::float64_t*>(pd);
f(pf64);
return *pd;
}
void h() {
double d = 1.0;
assert(g(d) == 2.0); // true???
assert(d == 1.0); // true???
}
Assuming an assert enabled build, what are your expectations for those
asserts? Today, an implementation is allowed to assume that a write
through a pointer of type std::float64_t cannot affect the value of an
object of type double. At what point would an optimizing compiler be
required to synchronize the write of *pf64 in f() with the read of d in
h()? Note that an optimizing compiler does not necessarily perform
operations in the order they appear in the source code.
In my opinion, unless the non-aliasing type restrictions are removed,
the following is required:
1. An operation very much like std::start_lifetime_as() is needed in
place of reinterpret_cast.
2. Another operation, perhaps the same operation with types reversed,
must be written at the point where the programmer wants changes to
be synchronized.
3. In between those two operations, the memory must only be accessed
via std::float64_t.
4. Before and after both operations, the memory must only be accessed
via double.
Tom.
> Also, insight into the intended purpose ofstd::float32_t andstd::float64_t would be welcome.
>
>
> I personally don't see how in most commonly used platforms (x86_64, ARM, etc..)std::float32_t andstd::float64_t would be anything other than an alias to float and double, no conversion necessary.
> If they have same bitwise representation and requirements, then I assume that yes you could just reinterpret_cast between them, that's what reinterpret_cast is for. But then again, probably unnecessary as I assume they will just be aliases of the thing you already wanted so casting is unnecessary.
No, that isn't what reinterpret_cast is for. reinterpret_cast allows for
the construction of a pointer or reference of a type that corresponds to
the actual type of the object at the provided location. It can't be used
for type punning except in certain cases involving non-aliasing types.
>
> -----Original Message-----
> From: Std-Proposals<std-proposals-bounces_at_[hidden]> On Behalf Of Paul Caprioli via Std-Proposals
> Sent: Monday, August 25, 2025 20:26
> To:std-proposals_at_[hidden]
> Cc: Paul Caprioli<paul_at_[hidden]>
> Subject: Re: [std-proposals] TBAA and extended floating-point types
>
> IEEE 754-2019 defines floating-point formats.
> All formats can be supported as arithmetic formats; that is, they may be used to represent floating-point operands or results.
> Specific fixed-width encodings for binary and decimal formats are defined for a subset of the formats.
> These interchange formats are identified by their size and can be used for the exchange of floating-point data between implementations.
>
> I assumestd::float16_t is a C++ arithmetic format.
> Note that it is unrelated to Unicode. See:https://en.wikipedia.org/wiki/UTF-16
>
> The C++ standard section [basic.extended.fp] does not make clear (to me at least) the intended purpose ofstd::float32_t andstd::float64_t.
> In particular, interoperability with arrays of float and double seems awkward at best.
>
> I'm requesting feedback as to whether reinterpret_cast should be made to work between floating-point types having identical representations.
> Should I bother to author such a proposal or would I be wasting my time?
I think you would either have to propose that such types do alias (in
which case no changes to reinterpret_cast would be needed) or you need
to come up with a more novel solution, perhaps something similar to what
is explored in P2626 <https://wg21.link/p2626>.
Consider:
void f(std::float64_t *pf64) {
*pf64 = 2.0;
}
double g(double *pd) {
std::float64_t *pf64 = reinterpret_cast<std::float64_t*>(pd);
f(pf64);
return *pd;
}
void h() {
double d = 1.0;
assert(g(d) == 2.0); // true???
assert(d == 1.0); // true???
}
Assuming an assert enabled build, what are your expectations for those
asserts? Today, an implementation is allowed to assume that a write
through a pointer of type std::float64_t cannot affect the value of an
object of type double. At what point would an optimizing compiler be
required to synchronize the write of *pf64 in f() with the read of d in
h()? Note that an optimizing compiler does not necessarily perform
operations in the order they appear in the source code.
In my opinion, unless the non-aliasing type restrictions are removed,
the following is required:
1. An operation very much like std::start_lifetime_as() is needed in
place of reinterpret_cast.
2. Another operation, perhaps the same operation with types reversed,
must be written at the point where the programmer wants changes to
be synchronized.
3. In between those two operations, the memory must only be accessed
via std::float64_t.
4. Before and after both operations, the memory must only be accessed
via double.
Tom.
> Also, insight into the intended purpose ofstd::float32_t andstd::float64_t would be welcome.
>
>
Received on 2025-08-26 19:22:41