std::launder
When to use std::launder?
Rule of thumb: If you use the pointer returned by std::construct_at or placement new, you usually don’t need std::launder.
However, if you have a pre-existing pointer to storage (std::byte*, char*, etc.) that was just reused with placement new, you should use std::launder before accessing it as the new type.
A common HFT use case is object pools or ring buffers that reuse preallocated memory with placement new to avoid allocation latency. After reconstructing an object in reused storage, std::launder is used to obtain a pointer to the new live object and avoid undefined behavior caused by stale compiler lifetime assumptions.
struct Tick {
uint64_t ts;
double px;
};
// Pre-allocated memory
alignas(Tick) std::byte slot[sizeof(Tick)];
Producer thread:
// Placement new
new(slot) Tick{ts, px};
consumer thread:
// Tell the compiler that this address is now used for a new type
auto* tick = std::launder(reinterpret_cast<Tick*>(slot));
Use std::launder when you know something the compiler doesn’t.
Write a comment