Hello all, I would like to discuss contracts and exception specifications (e.g., noexcept) specifically with respect to what Boost.Contract does. On one hand, it seems silly to allow a contract failure handler to throw an exception to only translate such an exception into a call to terminate() for noexcept functions. However, noexcept can be considered part of the function contract (namely, the contract that says the function shall not throw) and contract failure handlers should not be allowed to break such contract, not even when they are allowed to throw. For example consider a noexcept function fclose() that is called from a destructor without a try-catch statement (correctly so because fclose is declared noexcept). If fclose() is now allowed to throw when its preconditions fail, that will cause the destructor ~x() to throw as well?! void fclose(file& f) noexcept [[requires: f.is_open()]] ... class x { ~x() noexcept { fclose(f_); // f_ might not be open because of some bug... ... } file f_; }; (A point similar to the above is also made in N4160, in contrast with what argued in N4110.) Functions should honor their exception specifications (noexcept, etc.) even when their contracts fail and contract failure handlers are configured to throw. That is what Boost.Contract does (given that contract checking code appears within the function definition so it is subject to the exception specifications that appear in the enclosing function declaration): void fclose(file& f) noexcept { // This will call terminate()... boost::contract::guard c = boost::contract::function() .precondition([&] { BOOST_CONTRACT_ASSERT(f.is_open()); // ...even if this throws. } ; ... } int main() { boost::contract::set_precondition_failure( [] (boost::contract::from where) { // Re-throw exceptions (assertion_failure, user-defined, etc.). if(where != boost::contract::from_destructor) throw; std::terminate(); // But destructors never throw. } ); ... } Also note that a contract framework that allows to install failure handlers that throw exceptions should also pass some sort of parameter to the handler function to indicate if the contract failure happened in a destructor or not. That is so the failure handlers can choose to never throw for destructors, not even if class invariants (or postconditions) fails when checked by destructors. --Lorenzo