Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++20 bit_cast vs reinterpret_cast

According to the last meeting of the ISO C++ Committee, bit-cast will be introduced in C++20 standard.

I know that reinterpret_cast is not suitable for this job due to type aliasing rules but my question is why did they choose not to extend the reinterpret_cast to treat the object like it bit sequence representation and preferred to give this functionality as a new language construct?

like image 732
bogdan tudose Avatar asked Nov 20 '18 21:11

bogdan tudose


People also ask

Is reinterpret_cast safe?

the result of a pointer-to-pointer reinterpret_cast operation can't safely be used for anything other than being cast back to the original pointer type.

Can reinterpret_cast throw?

No. It is a purely compile-time construct. It is very dangerous, because it lets you get away with very wrong conversions.

What does reinterpret_cast mean in C++?

The reinterpret_cast allows the pointer to be treated as an integral type. The result is then bit-shifted and XORed with itself to produce a unique index (unique to a high degree of probability). The index is then truncated by a standard C-style cast to the return type of the function.


1 Answers

Well, there is one obvious reason: because it wouldn't do everything that bit_cast does. Even in the C++20 world where we can allocate memory at compile time, reinterpret_cast is forbidden in constexpr functions. One of the explicit goals of bit_cast is to be able to do these sorts of things at compile-time:

Furthermore, it is currently impossible to implement a constexpr bit-cast function, as memcpy itself isn’t constexpr. Marking the proposed function as constexpr doesn’t require or prevent memcpy from becoming constexpr, but requires compiler support. This leaves implementations free to use their own internal solution (e.g. LLVM has a bitcast opcode).

Now, you could say that you could just extend this specific usage of reinterpret_cast to constexpr contexts. But that makes the rules complicated. Instead of simply knowing that reinterpret_cast can't be used in constexpr code period, you have to remember the specific forms of reinterpret_cast that can't be used.

Also, there are practical concerns. Even if you wanted to go the reinterpret_cast route, std::bit_cast is a library function. And it's always easier to get a library feature through the committee than a language feature, even if it would receive some compiler support.

Then there's the more subjective stuff. reinterpret_cast is generally considered an inherently dangerous operation, indicative of "cheating" the type system in some way. By contrast, bit_cast is not. It is generating a new object as if by copying its value representation from an existing one. It's a low-level tool, but it's not a tool that messes with the type system. So it would be strange to spell a "safe" operation the same way you spell a "dangerous" one.

Indeed, if you did spell them the same way, it starts raising questions as to why this is reasonably well-defined:

float f = 20.4f; int i = reinterpret_cast<int>(f); 

But this is somehow bad:

float f = 20.4f; int &i = reinterpret_cast<int &>(f); 

And sure, a language lawyer or someone familiar with the strict aliasing rule would understand why the latter is bad. But for the lay person, if it is fine to use reinterpret_cast to do a bit-conversion, it is unclear why it is wrong to use reinterpret_cast to convert pointers/references and interpret an existing object as a converted type.

Different tools should be spelled differently.

like image 177
Nicol Bolas Avatar answered Sep 16 '22 11:09

Nicol Bolas