voidify
Section: 26.11.1 [specialized.algorithms.general] Status: C++23 Submitter: Jonathan Wakely Opened: 2023-01-30 Last modified: 2024-03-18
Priority: Not Prioritized
View all issues with C++23 status.
Discussion:
This is the resolution for NB comment GB-121
The voidify
helper breaks const-correctness, for no tangible benefit.
C++20 ballot comment US 215 also suggested removing it,
but failed to achieve consensus. That should be reconsidered.
The only claimed benefits are:
uninitialized_xxx
algorithms
to create objects in const storage
(including overwriting objects declared as const which is usually UB).
The caller should be responsible for using const_cast
if that's really desirable.
Implicitly removing 'const' is unsafe and unnecessary.
std::construct_at
.
This seems reasonable, but should be supported by adding a dedicated
function that doesn't conflate the type of the storage to write to
and the object to create, e.g. construct_at<const T>(ptr)
.
[Issaquah 2023-02-06; LWG]
Casey noted:
The claimed benefit is allowing the uninitialized_xxx
algorithms
to create objects of const and/or volatile type, which they cannot otherwise do
since they deduce the type of object to be created from the reference type
of the pertinent iterator. Creating const objects has some (marginal?) benefits
over using const pointers to mutable objects. For example, their non-mutable
members cannot be modified via casting away const without undefined behavior.
A unit test might take advantage of this behavior to force a compiler to
diagnose such undefined behavior in a constant expression.
The issue submitter was aware of this, but an open Core issue,
CWG 2514,
would invalidate that benefit. If accepted, objects with dynamic storage
duration (such as those created by std::construct_as
and the
std::uninitialized_xxx
algorithms) would never be const objects,
so casting away the const would not be undefined. So implicitly removing
const in voidify
would still allow modifying "truly const"
objects (resulting in undefined behaviour), without being able to create
"truly const" objects in locations where that actually is safe.
If CWG 2514 is accepted, the voidify
behaviour would be all
downside.
LWG requested removing the remaining casts from the proposed resolution,
relying on an implicit conversion to void*
instead.
Move to Immediate for C++23.
Previous resolution [SUPERSEDED]:
This wording is relative to N4928.
Modify 26.11.1 [specialized.algorithms.general], General, as indicated:
-4- Some algorithms specified in 26.11 [specialized.algorithms] make use of the exposition-only function
voidify
:template<class T> constexpr void* voidify(T& obj) noexcept { return
const_cast<void*>(static_cast<const volatilevoid*>(addressof(obj))); }
[2023-02-13 Approved at February 2023 meeting in Issaquah. Status changed: Immediate → WP.]
Proposed resolution:
This wording is relative to N4928.
Modify 26.11.1 [specialized.algorithms.general], General, as indicated:
-4- Some algorithms specified in 26.11 [specialized.algorithms] make use of the exposition-only function
voidify
:template<class T> constexpr void* voidify(T& obj) noexcept { return
const_cast<void*>(static_cast<const volatile void*>(addressof(obj))); }