You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
C.183 says that unions shouldn't be used for type punning but IMHO the guidance it provides on what to use instead leaves room for improvement. It mentions reinterpret_cast for casting to char*, unsigned char*, or std::byte. AFAIK we need to keep the following things in mind when punning types:
reinterpret_cast<bar>(foo) is UB if bar has stricter alignment requirements than the type of foo.
reinterpret_casting a pointer to a std::byte buffer to gadget* and then using this pointer to call member functions/access member variables is UB since no instance of gadget has been instantiated (object lifetime).
I guess it would be better to suggest a way which is safe with respect to all three points. In particular I would like to suggest replacing the reinterpret_cast paragraph by something along the following lines:
Use std::bit_cast (introduced with C++20) for type punning. If your standard library doesn't support std::bit_cast, yet, use std::memcpy instead. This is preferred over using union or reinterpret_cast since bitcast and memcpy reliably prevent undefined behavior due to violated alignment/aliasing rules. In practice modern compilers are often able to eliminate the copy.
Example:
// Assume sizeof(int) == sizeof(float) for these examples
void if_you_must_pun(float& x)
{
auto i = std::bit_cast<int>(x);
cout << i << '\n';
}
void if_you_must_pun_pre_cpp20(float& x)
{
int i;
memcpy(&i, &x, sizeof(x));
cout << i << '\n';
}
The text was updated successfully, but these errors were encountered:
C.183 says that unions shouldn't be used for type punning but IMHO the guidance it provides on what to use instead leaves room for improvement. It mentions
reinterpret_cast
for casting tochar*
,unsigned char*
, orstd::byte
. AFAIK we need to keep the following things in mind when punning types:reinterpret_cast<bar>(foo)
is UB ifbar
has stricter alignment requirements than the type offoo
.reinterpret_cast
ing a pointer to astd::byte
buffer togadget*
and then using this pointer to call member functions/access member variables is UB since no instance ofgadget
has been instantiated (object lifetime).reinterpret_cast
might lead to UB due to aliasing (example demonstrating this).I guess it would be better to suggest a way which is safe with respect to all three points. In particular I would like to suggest replacing the
reinterpret_cast
paragraph by something along the following lines:Use
std::bit_cast
(introduced with C++20) for type punning. If your standard library doesn't supportstd::bit_cast
, yet, usestd::memcpy
instead. This is preferred over usingunion
orreinterpret_cast
sincebitcast
andmemcpy
reliably prevent undefined behavior due to violated alignment/aliasing rules. In practice modern compilers are often able to eliminate the copy.Example:
The text was updated successfully, but these errors were encountered: