Remix.run Logo
monkeyelite 5 days ago

Do you see all the concepts you had to describe here?

> Unless you are a low-level systems developer it is unlikely to affect you.

Making new data structure is common. Serializing classes into buffers is common.

jandrewrogers 5 days ago | parent | next [-]

If you are doing something equivalent to placement new on top of existing objects, the compiler often sees that. If that is your case you can avoid it in most cases. That is not what std::launder is for. It is for an exotic case.

std::launder is a tool for object instances that magically appear where other object instances previously existed but are not visible to the compiler. The typical case is some kind of DMA like direct I/O. The compiler can’t see this at compile time and therefore assumes it can’t happen. std::launder informs the compiler that some things it believes to be constant are no longer true and it needs to update its priors.

monkeyelite 4 days ago | parent [-]

With placement new you need to hold on to the pointer. If you need to get an object back out of a buffer you need launder.

Std::vector needs launder.

jcelerier 5 days ago | parent | prev [-]

> Making new data structure is common. Serializing classes into buffers is common.

You don't want std::launder for any of that. If you must create object instances from random preexisting bytes you want std::bit_cast or https://en.cppreference.com/w/cpp/memory/start_lifetime_as.h...

TuxSH 4 days ago | parent [-]

Alas none of gcc/clang/msvc(?) have implemented start_lifetime_as, so if you want to create an object in-place and obtain a mutable pointer to it, you're stuck with the:

    return std::launder(static_cast<T*>(std::memmove(p, p, sizeof(T))));
trick until they properly implement it. For MMIO, reintepret_cast from integer is most likely fine.