|
Boost : |
Subject: Re: [boost] [Review:Contract] Contract Broken Handlers , BOOST_NO_EXCEPT and noexcept
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2012-08-30 20:03:42
Le 30/08/12 20:36, Lorenzo Caminiti a écrit :
> On Wed, Aug 29, 2012 at 4:52 PM, Vicente J. Botet Escriba
> <vicente.botet_at_[hidden]> wrote:
>> I would like to know if Boost.Contract could work when BOOST_NO_EXCEPT is
>> defined. I suspect that it can not at present, as the user needs to re-throw
>> the exception to know the broken nature. Maybe the handler could have the an
>> exception/error object as parameter instead.
> I'm not sure if this is possible... it will for sure complicate the
> implementation because I'll have to use status codes so signal
> failures instead of throw-catch statements.
>
> However, there's an issue for user with not using exceptions. Say I
> change the handlers to pass an object that indicates a contract
> failure:
>
> pre_broken ( contract::from const& context, contract::broken const& failure )
> {
> // ...
> }
>
> If there are no exceptions, this handler can only be called when a
> contract assertion is evaluated to false in which case failure will be
> properly set and that's OK:
>
> precondition( false ) // calls pre_borken with failure set
>
> However, on compilers where exceptions are supported/enabled the
> handler can also be called if an exception is thrown while evaluating
> the contract assertion:
>
> precondition( f() ) // if f throws, pre_broken is called with an
> active exception
>
> In this case the active exception can be of any type, in general
> unknown, so the lib can't handle it and convert it into a failure
> parameter without lost of information (the user instead could program
> the pre_broken handler with the knowledge of what type of exceptions
> are thrown by f).
>
> In addition users might want to throw their own exceptions:
>
> precondition( not empty() : true : throw empty_error() )
>
> Also in this case the lib can't catch and handle the user's exceptions
> to convert them into the failure parameter.
>
> Therefore, when exceptions are present the user will have to look at
> both active exceptions and the failure parameter in order to properly
> program the contract broken handlers. IMO, that is more confusing for
> the user than just having to deal with the active exception (which
> will be of type contract::broken only when a contract condition is
> evaluated to false and of some other type when evaluating the
> assertion condition threw).
Maybe be we can have both. When BOOST_NO_EXCEPTIONS is defined the
broken contract handler interface could have an additional parameter,
e.g. the error_code. Not that in this case can not throw of course and
any Boost library should avoid code using try/catch or throw sentences.
When BOOST_NO_EXCEPTIONS is not defined, the library will works as now.
>
>> In order to be able to use contracts in C++11 functions declared noexcept I
>> would need that the contract handler are declared noexcept also, in
>> particular when the contract is broken from a destructor, which is often
>> declared noexcept in C++11.
>> Maybe the library can provide some specific set handlers that expect a
>> noexcept handler for the destructor context.
> OK, I will do this when supporting C++11.
The same applies to throw() in C++03.
I would expect a different contract for contract broken from the
constructor and the others ones.
I will comment more about this in a replay to Andrej comment.
Best,
Vicente
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk