Section: 27.11.5 [uninitialized.copy] Status: C++20 Submitter: Jon Cohen Opened: 2018-01-24 Last modified: 2021-02-25 10:48:01 UTC
View all other issues in [uninitialized.copy].
View all issues with C++20 status.
I believe that uninitialized_copy is unable to meet its exception-safety guarantee in the presence of throwing move constructors:27.11 [specialized.algorithms]/1 has two statements of note for the specialized algorithms such as uninitialized_copy:
the provided iterators satisfy the InputIterator requirements (18.104.22.168 [input.iterators])
if an exception is thrown during the algorithm then there are no effects
[2018-01-24, Casey comments and provides wording]
This issue points out a particular hole in the "..if an exception is thrown in the following algorithms there are no effects." wording for the "uninitialized" memory algorithms (27.11 [specialized.algorithms]/1) and suggests a PR to patch over said hole. The true problem here is that "no effects" is not and never has been implementable. For example, "first != last" may have observable effects that an implementation is required to somehow reverse if some later operation throws an exception.Rather than finding problem case after problem case and applying individual patches, we should fix the root cause. If we alter the problematic sentence from [specialized.algorithms]/1 we can fix the issue once and for all and have implementable algorithms.
[2018-02-05, Priority set to 2 after mailing list discussion]
[2018-06 Rapperswil Thursday issues processing]
Status to Ready
[2018-11, Adopted in San Diego]
This wording is relative to N4713.
Modify 27.11 [specialized.algorithms] as indicated:
-1- […]Unless otherwise specified, if an exception is thrown in the following algorithms
there are no effects.
Modify 27.11.6 [uninitialized.move] as indicated (The removed paragraphs are now unnecessary):
template<class InputIterator, class ForwardIterator> ForwardIterator uninitialized_move(InputIterator first, InputIterator last, ForwardIterator result);
-2- Remarks: If an exception is thrown, some objects in the range [first, last) are left in a valid but unspecified state.template<class InputIterator, class Size, class ForwardIterator> pair<InputIterator, ForwardIterator> uninitialized_move_n(InputIterator first, Size n, ForwardIterator result);
-4- Remarks: If an exception is thrown, some objects in the range [first, std::next(first, n)) are left in a valid but unspecified state.