cpp_weekly icon indicating copy to clipboard operation
cpp_weekly copied to clipboard

reinterpret_cast and undefined behaviour

Open lcarlier opened this issue 3 years ago • 5 comments

Channel

C++Weekly

Topics

reinterpret_cast and undefined behaviour. What is allowed and not allowed. i.e. can we cast integer to pointer (e.g. for register access)? any risk doing so? type aliasing. Some example demonstrating what can go wrong when wrong type aliasing is done.

Length

5-10 minutes

lcarlier avatar Aug 21 '22 15:08 lcarlier

Reference to existing episode on this topic: https://youtu.be/L06nbZXD2D0

lefticus avatar Sep 03 '22 18:09 lefticus

Hi Jason, Thanks! That explains already a lot!

I was wondering whether there is also undefined behaviour when doing volatile reinterpret cast when accessing HW registers.

i.e.

uintptr_t CONFIG_REG_ADDR = 0x10000000;
uint32_t config_reg_val = *reinterpret_cast<volatile uint32_t*>(CONFIG_REG_ADDR);

Can we conclude that whenever data alignment is guaranteed, then reinterpret_cast won't produce UB?

Note that I've seen that using memcpy in this case gives the same ASM with optimized build but I'm still wondering if all the code I've seen so far is just full of UB or if we were just lucky.

lcarlier avatar Sep 04 '22 13:09 lcarlier

@lcarlier In this case you have a integer-to-pointer conversion, which as per the Standard is implementation defined. Most likely all microcontroller toolchains implement this correctly as it's the only way to access memory-mapped devices.

carlosgalvezp avatar Jan 10 '23 09:01 carlosgalvezp

see also https://github.com/lefticus/cpp_weekly/issues/245#issuecomment-2220224938 links with std::bit_cast, std::start_lifetime_as,...

Dharmesh946 avatar Jul 10 '24 11:07 Dharmesh946

Reference to existing episode on this topic: https://youtu.be/L06nbZXD2D0

1- Hi, how is it possible to get guarantees that memcpy is optimized away? 2- After the second memcpy (back to the storage), now S object exists in the storage and subsequent reinterpret_cast would be valid (I don't get how memcpy can create implicit lifetime objects without knowledge of the type, it looks like it's the usage of the destination pointer that determines the existence of objets in this case)? 3- how to use that for non default constructible objects? (I'm thinking about allocating the temporary with std::allocator::allocate and destroying it at the end of the function, but it won't be optimized away: https://godbolt.org/z/6zbTMEPnj)

Regards

Dharmesh946 avatar Jul 10 '24 11:07 Dharmesh946