Document: P3936R1
Authors: Corentin Jabot, Gonzalo Brito Gadeschi
Date: 2026-01-27
Audience: LWG
Resolves French NB comment FR-030-310. atomic_ref::address() currently returns T*, which makes it too easy to accidentally access the object non-atomically while live atomic_refs exist. The fix: return void* instead. You can still hash, compare, and index with it, but accessing the underlying object requires an explicit cast - making misuse visible. Works in constant expressions thanks to P2738R1's constexpr cast from void*.
Good fix. Returning
T*fromatomic_ref::address()was an invitation to write data races. You get the pointer back, forget you're supposed to use it only for hashing, and access the object directly.void*makes the non-atomic access require a deliberatestatic_cast. Harder to do by accident.The key enabler is P2738R1 -
constexprcast fromvoid*landed in C++26. Without that,void*would have been unusable during constant evaluation and the NB comment would have been harder to resolve. Nice when features compose.The return type is
COPYCV(T, void)*- preserving cv-qualification from the original type. Soatomic_ref<const int>::address()returnsconst void*. Correct and minimal. The exposition-only alias keeps the synopsis clean.The NB comment originally wanted
uintptr_t. EWG rejected it becauseuintptr_tisn't mandated and some architectures might have pointers larger than the largest integer.void*avoids both problems and the original P2835R7 authors considered it but dismissed it pre-P2738R1. Timing worked out.Clean NB comment resolution. Small scope, clear motivation, minimal wording change. These are the papers that keep the standard healthy.