This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.
destroy and fancy pointer operations must be non-throwingSection: 16.4.4.6 [allocator.requirements] Status: New Submitter: Billy O'Neal III Opened: 2018-09-07 Last modified: 2018-12-16
Priority: 3
View other active issues in [allocator.requirements].
View all other issues in [allocator.requirements].
View all issues with New status.
Discussion:
In annotating things required to be called by ~vector, Casey pointed out that several operations I guarded
with noexcept aren't actually mandated by the standard to be noexcept. However, the STL, and more
specifically here, containers, consider inability to destroy an element an unrecoverable condition. This is evidenced
for the whole STL by 16.4.6.14 [res.on.exception.handling]/3 "Every destructor in the C ++ standard library shall
behave as if it had a non-throwing exception specification.".
allocator::destroy and fancy pointer operations must be non-throwing for valid input, or the
containers don't make any sense. This is obvious for things like vector::~vector, but less obviously the
containers rely on these guarantees whenever inserting more than one element, etc.
Moreover, we too narrowly specify the domain of the pointer_traits::pointer_to requirement in the
Cpp17Allocator requirements, because any node-based container that uses container-internal sentinel
nodes needs to be able to form pointers to said sentinel nodes; that operation must also be non-throwing.
[2018-09 Reflector prioritization]
Set Priority to 3
Proposed resolution:
This wording is relative to N4762.
Modify 16.4.4.6 [allocator.requirements], Table 32 "Descriptive variable definitions" as indicated:
Table 32 — Descriptive variable definitions Variable Definition …YYthe type allocator_traits<Y>Zan allocator-aware container type (23.2.2 [container.requirements.general]) …ya value of type XX::const_void_pointerobtained by
conversion from a result value ofYY::allocate, or else a
value of type (possiblyconst)std::nullptr_t.zan lvalue of type Zsuch thatz.get_allocator() == ar1a reference to any member subobject of zna value of type XX::size_type.…
Modify 16.4.4.6 [allocator.requirements], Table 33 "Cpp17Allocator requirements" as indicated:
Table 33 — Cpp17AllocatorrequirementsExpression Return type Assertion/note
pre-/post-conditionDefault …pointer_traits<
X::pointer
>::pointer_to(r)X::pointerS same asp.
Throws: Nothing.pointer_traits<
X::pointer
>::pointer_to(r1)A value of type YY::pointeror
YY::const_pointerksuch that
*kisr1.
Throws: Nothing.…a.destroy(c)(not used) Effects: Destroys the object at c.
Throws: Nothing.c->~C()…
Modify 16.4.4.6 [allocator.requirements], p5, as indicated:
-5- An allocator type
Xshall satisfy theCpp17CopyConstructiblerequirements (Table 26). TheX::pointer,X::const_pointer,X::void_pointer, andX::const_void_pointertypes shall satisfy theCpp17NullablePointerrequirements (Table 30). No constructor, comparison function, copy operation, move operation, or swap operation on these pointer types shall exit via an exception.X::pointerandX::const_pointershall also satisfy the requirements for a random access iterator (24.3.5.7 [random.access.iterators]) and of a contiguous iterator (24.3.1 [iterator.requirements.general]) and operations in those requirements shall not exit via an exception so long as resulting iterators are dereferencable or past-the-end.
Modify 20.2.9.3 [allocator.traits.members], as indicated:
template<class T> static void destroy(Alloc& a, T* p);-6- Effects: Calls
-?- Throws: Nothing.a.destroy(p)if that call is well-formed; otherwise, invokesp->~T().