Boost logo

Boost :

Subject: Re: [boost] [variant2] Need rationale for never-empty guarantee
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2019-03-02 11:24:32

On 3/2/19 1:44 PM, Andrzej Krzemienski via Boost wrote:
> sob., 2 mar 2019 o 10:36 Andrey Semashev via Boost <boost_at_[hidden]>
> napisał(a):
>> On 3/2/19 11:56 AM, Andrzej Krzemienski via Boost wrote:
>>> This is where my imagination fails me. I cannot imagine why upon
>> bad_alloc
>>> I would be stopping the stack unwinding and determining size of my
>> vectors.
>>> This is why I ask about others' experience with real-world correct code.
>> That is not an unimaginable scenario. If you have two branches of code,
>> one requiring more memory but better performance, and the other that is
>> slower (or maybe lacking some other qualities but still acceptable) and
>> less resource consuming, operating on the same vector, you will want the
>> vector to stay valid if memory allocation fails. Although not
>> specifically with vectors, I had cases like this in real world.
> Thanks for sharing your experience.
> I am not sure we are on the same page here. Are you describing an operation
> where an operation on vector fails to allocate more storage and therefore
> throws and leaves the *value* of the vector unchanged (i.e., an operation
> with strong exception safety guarantee)? Or are you describing an operation
> that reuses memory owned by a vector and discards the vector's value? Boith
> these cases can be described as "never observing the value after a failed
> operation with a basic exception safety guarantee". Or are you describing a
> different situation?

As I mentioned, I usually don't rely on standard containers in
situations when I want complete control over memory allocations, so
vector is not the component I was talking about. However, the program
logic is often closer to the strong guarantee because I would normally
try allocating memory early, before the real work is done. Though, in
some instances some data is modified in non-harmful way in case of OOM.

There are a few instances when I want to "undo" the failed operation, in
which case the code relies on a particular "half-way through" state of
the program. The rollback process requires that there is a known number
of steps that were completed before failure, and the data associated
with those steps is in a valid state. From the failed operation
standpoint, this is a "strict" basic guarantee, from the underlying
components, like containers, this is almost certainly a strong guarantee.

I call "strict" basic guarantee, as opposed to just basic guarantee, a
case, where the program is allowed to have a *subset* of valid states
upon failure. Maybe there is a better term for this. I mean, for a
hypothetical initially non-empty vector, a basic guarantee push_back()
is allowed to leave the vector empty upon failure, but that might not be
an acceptable outcome for a higher level user's program. In my case, I
require a particular state of the program upon my operation failure.
This state may not be the same as before the operation started, but it
must at least include results of the steps the failed operation has
managed to complete. This allows these steps to be rolled back.

Boost list run by bdawes at, gregod at, cpdaniel at, john at