|
Boost : |
Subject: [boost] [contract] Strong exception safety guarantees
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2016-07-15 00:04:38
Hello all,
I've been considering adding a .except(...) construct to
Boost.Contract that will allow to specify conditions to check at
function exit but when the function body throws (in contrast to
postconditions that are checked at function exit but only when the
function body does not throw).
I think .except(...) could be used to assert strong exception safety
guarantees... (note that class invariants are already checked at exit
of public functions and also when the public function bodies throw,
but invariants are suited to assert only basic, and not strong,
exception safety guarantees).
That might help addressing a point made in P0147R0 under the
"Contracts and Exceptions" section:
``Some operations make stronger exception safety claims. In
particular, they claim that an exception thrown from a member function
will leave the state of an object unchanged from its state on function
entry. If we invalidate postconditions on exceptions, we appear to
have no mechanism to describe strong exception safety.''
For example, the following swap ensures to leave its arguments
unchanged when it throws:
void swap(std::string& a, std::string& b) {
boost::contract::old_ptr<std::string> old_a = BOOST_CONTRACT_OLDOF(a);
boost::contract::old_ptr<std::string> old_b = BOOST_CONTRACT_OLDOF(b);
boost::contract::guard c = boost::contract::function()
.postcondition([&] {
// Checked at function exit but only if body does not throw.
BOOST_CONTRACT_ASSERT(a == *old_b);
BOOST_CONTRACT_ASSERT(b == *old_a);
})
.except([&] {
// Checked if body throws (strong exception safety guarantees).
BOOST_CONTRACT_ASSERT(a == *old_a);
BOOST_CONTRACT_ASSERT(b == *old_b);
})
;
... // Body implementation (which might throw).
}
Would this be beneficial?
Thanks,
--Lorenzo
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk