Why std::launder Exists: The Placement New Bug Most C++ Developers Miss

This title could be clearer and more informative.Try out Clickbait Shieldfor free (5 uses left this month).

An explainer walks through why std::launder was introduced in C++17, using placement new to overwrite an object containing a const data member as a running example. It shows how the compiler caches const values and can return stale data after an in-place replacement, causing undefined behavior, and demonstrates how std::launder resets the optimizer's assumptions with zero runtime cost. It also covers the 'transparently replaceable' rule that determines when std::launder is actually needed and previews follow-up topics like polymorphic object replacement and union lifetime rules.

7m read timeFrom towardsdev.com
Post cover image

Questions this post answers

Why do I get undefined behavior when reading a const member after using placement new to overwrite an object in C++?

The compiler assumes const members never change and caches their value at compile time, so after placement new destroys the old object and constructs a new one at the same address, reading the const member through the old pointer can return the stale cached value instead of the new one. This is undefined behavior for types with const or reference members, defined by the C++ standard's basic.life rules from proposal P0137R1. Developers debugging placement-new memory reuse bugs can find deep C++ lifetime explainers curated on daily.dev.

When do I actually need to call std::launder after placement new in C++17?

std::launder is required only when the type is not transparently replaceable, meaning it has const non-static data members, reference members, or a base class or sub-object with either of those. For ordinary types without const or reference members, the old pointer automatically and safely refers to the new object without needing std::launder. Teams building custom allocators or memory pools track C++ lifetime rules like this via daily.dev.

Does std::launder add any runtime performance overhead in C++?

No, std::launder is a no-op at runtime and emits no extra CPU instructions. It functions purely as a compiler hint, acting as a semantic barrier that stops the optimizer from making unsafe assumptions about cached const or reference values after an object has been replaced in place. Engineers weighing low-level optimization trade-offs follow C++ memory-model deep dives on daily.dev.

1K Impressions