Boost logo

Boost :

Subject: Re: [boost] [outcome] Exception safety guarantees
From: Andrzej Krzemienski (akrzemi1_at_[hidden])
Date: 2017-05-30 15:30:05


2017-05-30 16:48 GMT+02:00 Howard Hinnant via Boost <boost_at_[hidden]>:

> On May 30, 2017, at 7:13 AM, Andrzej Krzemienski via Boost <
> boost_at_[hidden]> wrote:
> >
> > 2017-05-29 6:15 GMT+02:00 Howard Hinnant via Boost <
> boost_at_[hidden]>:
> >
> >> On May 28, 2017, at 6:36 PM, Andrzej Krzemienski via Boost <
> >> boost_at_[hidden]> wrote:
> >>>
> >>> 2017-05-28 2:10 GMT+02:00 Peter Dimov via Boost <boost_at_[hidden]
> >:
> >>>
> >>>>
> >>>> (It's the same for move, by the way. There are people who prefer
> >>>> destroy-only for moved-from objects. The standard library does not
> agree
> >>>> with them, this time because Howard.)
> >>>>
> >>>
> >>> Acknowledged. But what do the STL containers/algorithms do with the
> >>> moved-from objects other than to destroy them or reset them?
> >>
> >> They are allowed to do everything with moved-from objects that they are
> >> allowed to do with objects that haven’t been moved from. For example
> sort
> >> is allowed to move construct from, move assign to, move assign from,
> swap,
> >> and compare objects, whether or not they are in a moved from state.
> >> std::sort requires objects to satisfy strict weak ordering. This means
> >> among other things that x < x is always false, even if x is in a
> moved-from
> >> state.
> >>
> >> In summary, being in a moved-from state does not excuse an object from
> >> meeting the requirements of the algorithm it is being used with. It
> only
> >> excuses the object from having a specified state (in most cases).
> >>
> >> Real-world examples:
> >>
> >> An old std::reverse implementation, when given a range with an odd
> length,
> >> would swap the middle element with itself. This results in a moved-from
> >> object being self-move-assigned if the generic std::swap is being
> used. It
> >> just has to work. By work, I mean that the self-move-assignment of a
> >> moved-from-object has to leave the object in a valid but unspecified
> >> state. If it does this, then self-swap is a non-modifying operation,
> and
> >> the reverse algorithm gives the correct result.
> >>
> >> The std::remove algorithm returns moved-from objects back to the client
> >> (those at the end of the sequence that have been “removed”). The
> client is
> >> free to do anything he wants with those objects as long as that
> operation
> >> does not have a precondition. Although the typical use case is for the
> >> client to delete those “removed” elements, that is by no means
> required, or
> >> the only use case.
> >>
> >> I know of no sort implementation that compares moved-from objects
> (though
> >> I have not done a rigorous survey either). But it is quite possible
> that a
> >> sort algorithm could compare a moved-from object against itself, and
> still
> >> be a correct algorithm, as long as x < x (or comp(x, x)) _always_
> returns
> >> false.
> >>
> >
> > Ok, I think I asked the wrong question. I asked:
> >
> > what do the STL containers/algorithms do with the moved-from objects
> >>
> >
> > But what I actually meant was:
> >
> > "when an STL algorithm *causes* an object to obtain a
> valid-but-unspecified
> > *during its operation* , what does it later do with this object other
> than
> > to destroy it or re-set it (or leave it like this for the caller -- for
> the
> > caller to destroy it or reset it)?"
> >
> > Because, if I myself am passing objects in valid-but-unspecified state to
> > STL algorithms, I am already doing something wrong (I should have
> probably
> > destroyed or reset these objects).
>
> I had interpreted your question the way you meant it. My answer doesn’t
> change.
>

Than I do not understand your answer. std::sort, apart from what it is
allowed to do, is also require to produce the output range that is the
permutation of the input range. Assuming no moved-from states on input, if
for some reason it starts to put objects in a moved-from state and then
using this value for sorting further, even if moved-from state is
well-ordered, you will get this moved from state in the output range, but
it was not in the input range.

Regarding your std::reverse example, yes, self-swap, and possibly cloning
of the moved-from state should also be part of minimum safety requirements.

Regards,
&rzej;


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk