In his recent talk “Type punning in modern C++” Timur Doumler said that std::bit_cast cannot be used to bit cast a float into an unsigned char[4] because C-style arrays cannot be returned from a function. We should either use std::memcpy or wait until C++23 (or later) when something like reinterpret_cast<unsigned char*>(&f)[i] will become well defined.
In C++20, can we use an std::array with std::bit_cast,
float f = /* some value */;
auto bits = std::bit_cast<std::array<unsigned char, sizeof(float)>>(f);
instead of a C-style array to get bytes of a float?
Yes, this works on all major compilers, and as far as I can tell from looking at the standard, it is portable and guaranteed to work.
First of all,
std::array<unsigned char, sizeof(float)>is guaranteed to be an aggregate (https://eel.is/c++draft/array#overview-2). From this follows that it holds exactly asizeof(float)number ofchars inside (typically as achar[], although afaics the standard doesn't mandate this particular implementation - but it does say the elements must be contiguous) and cannot have any additional non-static members.It is therefore trivially copyable, and its size matches that of
floatas well.Those two properties allow you to
bit_castbetween them.