
On Wed, Aug 29, 2012 at 4:52 PM, Vicente J. Botet Escriba <vicente.botet@wanadoo.fr> 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).
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.
BTW, could the ALL CAPITAL |FROM_CONSTRUCTOR, ... enumeration literal|s be renamed to lower case from_constructor, ...?
Oops, I didn't look what's Boost standard to name enumeration... I'll look it up and fix this if needed. Thanks, --Lorenzo