Subject: Re: [Boost-bugs] [Boost C++ Libraries] #12542: multi_index constraint violation if rollback callable is passed, but doesn't correct the issue
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2016-10-23 18:30:39
#12542: multi_index constraint violation if rollback callable is passed, but
doesn't correct the issue
-----------------------------------+-------------------------
Reporter: Jon Kalb <jonkalb@â¦> | Owner: joaquin
Type: Bugs | Status: new
Milestone: To Be Determined | Component: multi_index
Version: Boost 1.61.0 | Severity: Problem
Resolution: | Keywords:
-----------------------------------+-------------------------
Comment (by anonymous):
Hi Jon,
OK, I think I'm buying your point. My thought process has been somewhat
convoluted, though, let me explain:
Re-reading the specs for non-rollback `modify` I noticed this (italics
mine):
"'''Exception safety:''' Basic. If an exception is thrown by some user-
provided operation ''(except possibly `mod`)'', then the element pointed
to by `position` is erased."
So I was like, am I really allowing the user to throw inside `mod` without
the lib checking the consistency of the element? In fact I am:
{{{
template<typename Modifier>
bool modify_(Modifier& mod,node_type* x)
{
mod(const_cast<value_type&>(x->value()));
BOOST_TRY{
...
}}}
and this opens up a real case of consistency breach:
{{{
struct element
{
std::string x,y;
};
...
i.modify(it,[](element& e){
e.x="whatever"; // dynamic allocation, can throw
e.y="and ever"; // idem
});
}}}
This example can throw in between assigments to `x` and `y`, making
`modify` return without checking for consistency (uniqueness,
rearranging). So, this is a design flaw in `modify` (both with and without
rollback) and I have to correct it. We have two options when `mod` throws:
delete the element or go ahead with rearranging; as throwing is an
indication of failure, I think the natural thing to do is delete, and
moreover going ahead in the rollback version is problematic, since the
element was left in mid-modification and `rollback` could expect something
else (your opinion on this point most welcome). The current situation is
then
* `mod` is not guarded against throws but is guarded against inconsistency
(rollback or element deletion if no rollback provided)
* `rollback` is guarded against throws (element deletion) but is not
guarded against inconsistency
and after I correct the problem with `mod` we'll have
* `mod` is guarded against throws (element deletion) and inconsistency
(rollback or element deletion if no rollback provided)
* `rollback` is guarded against throws (element deletion) but not guarded
against inconsistency
and now I'm leaning more towards your position out of considerations of
symmetry:
* `mod` is guarded against throws (element deletion) and inconsistency
(rollback or element deletion if no rollback provided)
* `rollback` is guarded against throws and inconsistency (element
deletion)
So, I'l put myself to clean this up. The changes required are not entirely
trivial, though, and require extra care to get them right (as I guess
you'll guess after this conversation), so it's going to take me some weeks
before I find the time --I'm also in the process of finishing something up
for Boost submission, so my current C++ slot is occupied.
Thanks for the interesting discussion,
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/12542#comment:5> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:20 UTC