Date: Wed, 2 Jul 2025 11:44:58 +0100
On Wed, 2 Jul 2025 at 11:21, Peter Bindels <dascandy_at_[hidden]> wrote:
> On Wed, Jul 2, 2025 at 12:04 PM Jonathan Wakely via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
>>
>>
>> On Wed, 2 Jul 2025 at 02:25, Howard Hinnant via Std-Proposals <
>> std-proposals_at_[hidden]> wrote:
>>
>>> On Jul 1, 2025, at 5:03 PM, Jonathan Wakely via Std-Proposals <
>>> std-proposals_at_[hidden]> wrote:
>>> >
>>> > See
>>> https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3182r1.html
>>> >
>>>
>>> I’ve prototyped the solution in
>>> https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3182r1.html
>>> and it only works if the value_type move constructor has the strong
>>> exception safety guarantee. If it has only the basic exception safety
>>> guarantee, the pop_value implementation in section 6.1 still loses the
>>> value on exception. This completely negates the argument that we have the
>>> technology now to workaround the C++98 concerns regarding exception safety.
>>>
>>> The only way I see to make pop_value exception safe is for it to require
>>> is_nothrow_move_constructible_v<value_type>. *Then* we fully negate the
>>> C++98 exception safety issue. And then the Guard is not needed (as noted
>>> in P3182).
>>>
>>
>> I think you also need the underlying container's pop_back() to be
>> non-throwing. None of our existing sequence containers have a noexcept
>> pop_back(), because of the Lakos rule.
>>
>> I wrote a draft proposal for std::stack::pop() a few years ago that I
>> never finished writing and abandoned because of the problem with a
>> potentially-throwing pop_back:
>> https://isocpp.org/files/papers/D2518R0.html
>>
>
> https://github.com/dascandy/s2/blob/master/include/s2/detail/vector.h#L123
>
> It's definitely a thing that's possible to implement, but it indeed
> requires full control over the type's implementation, and it strictly
> requires nothrow destructible. I do believe that the implementation I
> linked is safe for types that can throw on move, with the caveat that if
> you have such a queue or stack and fail to pop the value off... then what?
>
> As far as I can tell the backward compatibility issues, lack of marked
> improvement and minor details are what's holding this back, but practically
> it seems viable.
>
It's certainly possible to implement an exception-safe
Container::pop_back(), that wasn't my point. A container *adaptor* like
std::stack cannot provide an exception-safe std::stack<C>::pop() without
knowing whether C::pop_back() is safe, and it can't know that generically.
> On Wed, Jul 2, 2025 at 12:04 PM Jonathan Wakely via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
>>
>>
>> On Wed, 2 Jul 2025 at 02:25, Howard Hinnant via Std-Proposals <
>> std-proposals_at_[hidden]> wrote:
>>
>>> On Jul 1, 2025, at 5:03 PM, Jonathan Wakely via Std-Proposals <
>>> std-proposals_at_[hidden]> wrote:
>>> >
>>> > See
>>> https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3182r1.html
>>> >
>>>
>>> I’ve prototyped the solution in
>>> https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3182r1.html
>>> and it only works if the value_type move constructor has the strong
>>> exception safety guarantee. If it has only the basic exception safety
>>> guarantee, the pop_value implementation in section 6.1 still loses the
>>> value on exception. This completely negates the argument that we have the
>>> technology now to workaround the C++98 concerns regarding exception safety.
>>>
>>> The only way I see to make pop_value exception safe is for it to require
>>> is_nothrow_move_constructible_v<value_type>. *Then* we fully negate the
>>> C++98 exception safety issue. And then the Guard is not needed (as noted
>>> in P3182).
>>>
>>
>> I think you also need the underlying container's pop_back() to be
>> non-throwing. None of our existing sequence containers have a noexcept
>> pop_back(), because of the Lakos rule.
>>
>> I wrote a draft proposal for std::stack::pop() a few years ago that I
>> never finished writing and abandoned because of the problem with a
>> potentially-throwing pop_back:
>> https://isocpp.org/files/papers/D2518R0.html
>>
>
> https://github.com/dascandy/s2/blob/master/include/s2/detail/vector.h#L123
>
> It's definitely a thing that's possible to implement, but it indeed
> requires full control over the type's implementation, and it strictly
> requires nothrow destructible. I do believe that the implementation I
> linked is safe for types that can throw on move, with the caveat that if
> you have such a queue or stack and fail to pop the value off... then what?
>
> As far as I can tell the backward compatibility issues, lack of marked
> improvement and minor details are what's holding this back, but practically
> it seems viable.
>
It's certainly possible to implement an exception-safe
Container::pop_back(), that wasn't my point. A container *adaptor* like
std::stack cannot provide an exception-safe std::stack<C>::pop() without
knowing whether C::pop_back() is safe, and it can't know that generically.
Received on 2025-07-02 10:45:16