Loading collection data...
Collections are a way for you to organize kata so that you can create your own training routines. Every collection you create is public and automatically sharable with other warriors. After you have added a few kata to a collection you and others can train on the kata contained within the collection.
Get started now by creating a new collection.
Good point; it's an easily missable diference between C and C++. :)
It looks like most major C++ compilers actually do allow
union
-based type punning as an extension, even though it isn't strictly required.GCC explicitly allows it even when
-fstrict-aliasing
is enabled, as long as you don't access union elements via a pointer.I had trouble finding an official reference on how Clang behaves, but I played around in Compiler Explorer for a bit and both GCC and Clang handled
union
-based punning gracefully even on-O3
. Neither issued any warnings with-Wall -Wextra -Wpedantic
enabled.So it's probably fine to type-pun with unions on the major compilers, but I imagine things could get """fun""" quickly in lesser-used environments.
interestingly,
union
type punning is undefined behavior in C++ but not in CThis solution is pretty slick, but it unfortunately invokes undefined behavior in the two pointer casts due to C++'s type aliasing rules. Essentially, referring to a value of type
T
through a pointer of a different typeU*
is undefined behavior unlessU
is thesigned
/unsigned
equivalent ofT
; or at least one type ischar
,unsigned char
, orstd::byte
.Many compilers are cautious and will try not to screw you over for doing this, but it can result in your code breaking in unpredictable ways on different compilers or different optimization levels.
To my knowledge, the only safe way to treat a
float
as auint32_t
in C++17 is to usechar*
(or similar) pointers to copy bytes from thefloat
value into a separateuint32_t
value, like howstd::memcpy
does. (Trying to do this via a union type is also undefined behavior, so you unfortunately are required to copy the bytes into a separate buffer object.)C++20 has
std::bit_cast
, which is designed exactly for this purpose, but Codewars unfortunately does not support C++20 yet. :(