Page MenuHomePhabricator

Fix a violation of C++ standard rules that unions cannot be switched.
ClosedPublic

Authored by PiRK on Jan 3 2021, 14:00.

Details

Summary

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 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

Test Plan

ninja all check-all

Diff Detail

Repository
rABC Bitcoin ABC
Lint
Lint Not Applicable
Unit
Tests Not Applicable