> Type punning in C++ is not like C. As per the C++ standard, one cannot use unions to convert the bit type. A discussion about this can be found [[https://stackoverflow.com/questions/25664848/unions-and-type-punning|here]]. In C++, a union is supposed to only hold one type at a time. It's intended to be used only as std::variant. Switching types is undefined behavior.
>
> In fact, C++20 has a special casting function, called bit_cast that solved this problem.
>
> Why has it been working so far? Because some compilers tolerate using unions and switching types, like gcc.
>
> One important thing to mention is that performance is generally not affected by that memcpy. Compilers are smart enough to convert that to a memory cast when possible. But we have to do it the right way, otherwise, it's jut undefined behavior that depends on the compiler.
Note that @practicalswift verified that the bytecode generated by `clang++ -O1` is identical before and after the change: https://github.com/bitcoin/bitcoin/pull/18167#issuecomment-587488632
This is a backport of Core PR18167