From: Jens Auer on
I am trying to implement some tools to ease design by contract. To
check invariants automatically at the beginning and end of member
functions, I intend to use a helper object which does this in RAII-
fashion:

class InvariantViolation: public std::logic_error
{

};

class InvariantChecker
{
public:
InvariantChecker( boost::function< bool () > const& predicate):
mPredicate( predicate )
{
_check();
}

~InvariantChecker()
{
_check(); // may throw! What else to do?
}

private:
void _check() const
{
if ( !mPredicate() )
{
throw InvarianViolation();
}
}

boost::function< bool () > mPredicate;
};

// usage example
class IntStack
{
public:
int pop()
{
InvariantChecker( boost::bind( std::greater_equal(), 0, mSize );
// check preconditions and do work. Then check postconditions.
}
private:
int mSize;
};

I don't know how to automatically implement the invariant check
without throwing in the destructor of the InvariantChecker class. I
know that is said everywhere to not throw exceptions in the
destructor, but what other options are there to execute the check
automatically at the start and end of a function?

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: marcin.sfider on
On Jun 29, 10:35 pm, Jens Auer <jens.muad...(a)googlemail.com> wrote:
> I am trying to implement some tools to ease design by contract. To
> check invariants automatically at the beginning and end of member
> functions, I intend to use a helper object which does this in RAII-
> fashion:
>
> class InvariantViolation: public std::logic_error
> {
>
> };
>
> class InvariantChecker
> {
> public:
> InvariantChecker( boost::function< bool () > const& predicate):
> mPredicate( predicate )
> {
> _check();
> }
>
> ~InvariantChecker()
> {
> _check(); // may throw! What else to do?
> }
>
> private:
> void _check() const
> {
> if ( !mPredicate() )
> {
> throw InvarianViolation();
> }
> }
>
> boost::function< bool () > mPredicate;
>
> };
>
> // usage example
> class IntStack
> {
> public:
> int pop()
> {
> InvariantChecker( boost::bind( std::greater_equal(), 0, mSize );
> // check preconditions and do work. Then check postconditions.
> }
> private:
> int mSize;
>
> };
>
> I don't know how to automatically implement the invariant check
> without throwing in the destructor of the InvariantChecker class. I
> know that is said everywhere to not throw exceptions in the
> destructor, but what other options are there to execute the check
> automatically at the start and end of a function?
>
The problem is that if the code between creation and destruction of
InvariantChecker throws and then InvariantChecker destructor throws
the program terminates and neither exception will do what it should.

To work this out you could add try/catch after creation of each
InvariantChecker like this:

InvariantChecker ge_inv_check(
boost::bind(std::greater_equal(), 0, mSize));
try {

<your code here>

} catch (...) {
// tell the checker not to throw in destructor
ge_inv_check.dontThrowInDestructor();
throw;
}

When wrapped with macros it could be useable I suppose.

Cheers
Sfider


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Martin B. on
Jens Auer wrote:
> I am trying to implement some tools to ease design by contract. To
> check invariants automatically at the beginning and end of member
> functions, I intend to use a helper object which does this in RAII-
> fashion:
>
> class InvariantViolation: public std::logic_error
> {
>
> };
>
> class InvariantChecker
> {
> public:
> InvariantChecker( boost::function< bool () > const& predicate):
> mPredicate( predicate )
> {
> _check();
> }
>
> ~InvariantChecker()
> {
> _check(); // may throw! What else to do?
> }
>

I've never used uncaught_exception() myself, but if you wrap the
_check() in if(!uncaught_exception()) then you can handle the case where
your dtor is called for stack-unwind in case of exception. Or so I
guess. :-)

br,
Martin

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Nick Hounsome on
On 29 June, 21:35, Jens Auer <jens.muad...(a)googlemail.com> wrote:
> I am trying to implement some tools to ease design by contract. To
> check invariants automatically at the beginning and end of member
> functions, I intend to use a helper object which does this in RAII-
> fashion:
>
> class InvariantViolation: public std::logic_error
> {
>
> };
>
> class InvariantChecker
> {
> public:
> InvariantChecker( boost::function< bool () > const& predicate):
> mPredicate( predicate )
> {
> _check();
> }
>
> ~InvariantChecker()
> {
> _check(); // may throw! What else to do?
> }
>
> private:
> void _check() const
> {
> if ( !mPredicate() )
> {
> throw InvarianViolation();
> }
> }
>
> boost::function< bool () > mPredicate;
>
> };
>
> // usage example
> class IntStack
> {
> public:
> int pop()
> {
> InvariantChecker( boost::bind( std::greater_equal(), 0, mSize );
> // check preconditions and do work. Then check postconditions.
> }
> private:
> int mSize;
>
> };
>
> I don't know how to automatically implement the invariant check
> without throwing in the destructor of the InvariantChecker class. I
> know that is said everywhere to not throw exceptions in the
> destructor, but what other options are there to execute the check
> automatically at the start and end of a function?

It's not a problem provided that you don't check invariants in the
destructors of checked classes.

The reason for not throwing in destructors is because of the effects
of throwing whilst unwinding a stack due to a previous thrown
exception - There is no logical way to handle this so the runtime has
to call std::terminate.

There should be no need to check in the destructor anyway. In fact it
is would be logically wrong - If the invariant is checked on exit from
every other method then it must be valid on entry to the dtor (barring
random memory corruption) and also invariants are not usualy valid on
exit from a dtor anyway because the object is destroyed.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Vladimir Jovic on
Jens Auer wrote:
> I don't know how to automatically implement the invariant check
> without throwing in the destructor of the InvariantChecker class. I
> know that is said everywhere to not throw exceptions in the
> destructor, but what other options are there to execute the check
> automatically at the start and end of a function?
>

Log the error (if possible with backtrace). Optionally, you can
terminate the program. That will happen anyway, if you do not handle the
exception in the destructor.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]