When to use 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 (or std::byte*, char*, etc.) to storage 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
No comments yet.