std::unique_ptr::reset checks for managed pointer nullity?
c++, c++11, delete-operator, language-lawyer, unique-ptr
Solution
Yes, the check for non-null is required by the standard (C++11, `[unique.ptr.single.modifiers]§4`):
void reset(pointer p = pointer()) noexcept;
4 Effects: assigns `p` to the stored pointer, and then if the old value of the stored pointer, `old_p`, was not equal to `nullptr`, calls `get_deleter()(old_p)`. [ Note: The order of these operations is significant because the call to get_deleter() may destroy `*this`. —end note ]
(emphasis mine)
Discussion: An alternative way to standardise it would be to put the "burden" on the user of the class, i.e. require all deleters (the default one and any custom ones) to work fine when invoked on a null pointer.
However, I understand the idea was to enable functions like `free()` and even things like a hypothetical `unlock_mutex(Mutex*)` to work as deleters out-of-the-box, regardless of how/if they handle null pointers. So putting this check into the `unique_ptr` itself broadens the selection of deleters which can be used directly.
Problem
I've been reading about the C++11 smart pointers in order to use them on my sources, the documentation I've been reading is the one on cppreference.com; while reading about the `std::unique_ptr`, on the `reset` function there's a documentation that seems incorrect to me (emphasis mine): Replaces the managed object. Given `current_ptr`, the pointer that was managed by `*this`, performs the following actions, in this order: - Saves a copy of the current pointer `old_ptr = current_ptr`. - Overwrites the current pointer with the argument `current_ptr = ptr`. - If the old pointer was non-empty, deletes the previously managed object `if(old_ptr != nullptr) get_deleter()(old_ptr)`. In the C++ standard documentation, we can read the well known delete null pointer feature: Extract from `n3690` standard 5.3.5 Delete (emphasis mine): If the value of the operand of the delete-expression is not a null pointer value, then: — If the allocation call for the new-expression for the object to be deleted was not omitted, the delete-expression shall call a deallocation function. The value returned from the allocation call of the new-expression shall be passed as the first argument to the deallocation function. — Otherwise, the delete-expression will not call a deallocation function. So, I'm wondering why cppreference says that the `unique_ptr::reset` function checks for the nullity of the managed pointer before it's deletion even while te standard says that no deallocation function would be called over a null pointer (that's why the cppreference documentation seems incorrect to me). Is kind of obvious that I must be mistaken and there must be a reason to do things this way, but I'm unable to imagine what reason it could be. Any hints? PS: Where in the standard is defined how the `std::unique_ptr` must be implemented or behave? In the 20.9.1 Class template `unique_ptr` I cannot found anything about the check-for-nullity stuff.