C++ Logo

std-discussion

Advanced search

Old-style casts and prvalue materialization alternatives to reinterpret_cast

From: Edward Catmur <ecatmur_at_[hidden]>
Date: Mon, 29 Mar 2021 08:31:13 +0100
Consider:

float const& f = 1.f;int const i = (int&) f;

Per expr.cast/4 <http://eel.is/c++draft/expr.cast#4> this should be
considered as, in order:


   - a const_­cast,
   - a static_­cast,
   - a static_­cast followed by a const_­cast,
   - a reinterpret_­cast, or
   - a reinterpret_­cast followed by a const_­cast,

Clearly a static_­cast<int const&> followed by a const_­cast<int&> is viable
<https://godbolt.org/z/Tr8b96xhq>; it will construct a prvalue int
initialized from the float (with value 1), materialize it, bind it to a
const reference, cast away const, and then perform lvalue-to-rvalue
conversion resulting in an int with value *1*.

However, all compilers that I have checked instead initialize i to
*0x3f800000*, indicating that they took the last option of
reinterpret_­cast<int
const&> followed by const_­cast<int&>. (If the UB offends you, consider
changing int to unsigned char.)

This is somewhat related to CWG 909
<http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#909>,
involving conversion functions, which was closed NAD.

Should the Standard be changed to reflect implementation behavior, or
should compiler vendors be persuaded to change their ways? I have a feeling
that obeying the letter of the Standard here would silently break quite a
lot of code, notwithstanding that such code would be pretty dubious already.

Received on 2021-03-29 02:31:27