6 ms·
reinterprate_cast has it's place (mainly in the embdedded/kernel/low level software world) but unless you are in one of the fields where it is actually needed (
by CuriousCosmic 5y ago
reinterprate_cast has it's place (mainly in the embdedded/kernel/low level software world) but unless you are in one of the fields where it is actually needed (aforementioned places where type punning is just nature of the beast) then there's really not a better alternative.
- ncmncm 5y agoNow there is: see bit_cast above. But in fact memcpy to a local is very often a better alternative, pre-C++20. Compilers optimize it away.
- gpderetta 5y agoIt is different though. Bit cast returns a new object, while reinterpret cast is in place. It doesn't matter for small objects, but it can matter for large ones.
- 10000truths 5y agoIf the compiler’s optimization passes determine that the bitcasted-from and bitcasted-to objects are never simultaneously live, then copying can be easily elided.
- tsimionescu 5y agoUsually, you either care about 0-copy, in which case you don't want to rely on "if the compile can tell", or you don't care about 0-copy, in which case it doesn't matter that the compiler did it. reinterpret_cast guarantees that it is in-place, so it's the right tool for 0-copy.
- ncmncm 5y agoOr, you check. Elided copy is very rarely UB, something that cannot be said of uses of reinterpret_cast.
- tsimionescu 5y agoYou check today. What if tomorrow something changes? What if your network application starts dropping packets because it can't process them fast enough because an apparently unrelated change suddenly messed with a two year old optimization?
- ncmncm 5y agoThen you fix it. Correct code is rarely hard to make faster. What when your compiler starts to take advantage of latitude extended by the Standard, leading your program to produce sporadic, non-reproducible wrong results? It is best not to code any UB. But it is often hard to be certain, around reinterpret_cast.
- tsimionescu 5y ago> Correct code is rarely hard to make faster. You rarely want to be spending time fiddling with the optimizer. Your code shouldn't rely on the optimizer to be efficient: don't use constructs whose semantics mean you are making a copy in places where you don't want a copy. reintrepret_cast is hard to use correctly, but you only have to get it right once, and it has the right semantics, so no compiler changes will suddenly make it wrong or slow. memcpy and bit_cast have the wrong semantics, so they may change for unexpected reasons. In fact, it would be perfectly reasonable for a future version of the compiler to never optimize away the copy implied by memcpy and bit_cast.
- 10000truths 5y agoDetermining local variable lifetimes is a fundamental feature of a compiler. Literally any compiler that does register allocation can and will merge local variables that aren't simultaneously live. Because it turns out that the problem of fitting lots of variables into minimum registers is remarkably similar to the problem of fitting lots of variables into minimum registers + minimum stack space. So yes, you can confidently rely on gcc or clang to merge local variables, even at -O1. If they suddenly don't do that after an update, it's a serious regression, and their mailing lists should be more than happy to receive that bug report.
- gpderetta 5y agoThe problem is that if you are bitcasting, say, from a memory buffer coming from a read() call it is very hard for the compiler to prove that bitcasted copy is the only live one, especially across function calls. For small objects bitcast works just fine because the result end up in registers were you would have loaded the original objects anyway.
- CuriousCosmic 5y agoI think bit_cast may finally solve the last major use case of reinterpret_cast (building type safe memory mapped device objects) but I haven't sat down and tried to verify this yet. Unfortunately there are also still a lot of platforms that have yet to get C++20 support and memcpy is not a viable alternative. Hopefully this is less of an issue in the future as major MCU orgs like TI have started switching to LLVM/Clang based compilers which can follow upstream with little to no changes needed. Edit: I just did some digging and bit_cast does not work for the aforementioned use case since it can copy the data to a new location in memory. This prevents us from being able to reliably use it to write to memory registers.