ARTICLE AD BOX
I need to interpret 4 bytes at the beginning (or at some 4-byte aligned offset) of a raw memory mapped buffer as an integer.
The "classical way" with reinterpret_cast is undefined behaviour. Below three alternatives that are compiled into the the exact same assembly code by gcc and clang, see https://godbolt.org/z/13fsTqfxq.
Which is the "best" way (in C++20), what are the pros and cons? (assuming the compiler supports all options)
Would the answer be different if the buffer was declared volatile?
#include <bit> #include <memory> #include <new> #include <cstdint> #include <cstring> extern unsigned char * buffer; // page aligned uint32_t read_reinterpret_cast() { return *reinterpret_cast<uint32_t*>( buffer ); } uint32_t read_reinterpret_launder() { return * std::launder( reinterpret_cast<uint32_t*>( buffer ) ); } uint32_t read_bit_cast() { uint32_t * t = reinterpret_cast<uint32_t*>( buffer ); return std::bit_cast<uint32_t>( *t ); } #if __cpp_lib_start_lifetime_as uint32_t read_start_lifetime_as() { return *std::start_lifetime_as<uint32_t>(buffer); // C++23 } #endif uint32_t read_memcpy() { uint32_t t = {}; memcpy( &t, buffer, sizeof(uint32_t) ); return t; }