C++ Logo


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

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
const&> followed by const_­cast<int&>. (If the UB offends you, consider
changing int to unsigned char.)

This is somewhat related to CWG 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