
Hi Lorenzo, I think that installing broken contract handlers will not work correctly when a program is linking with DLLs on Windows. I do not know how dynamic linking works on Linux. Here is a sketch of a sample program that fails to work as expected. The program consists of two projects: one builds a DLL, the other builds an executable that links with the DLL: DLL: ==================================== # include <contract.hpp> # include "testdll.h" CONTRACT_FUNCTION ( int (give1) () postcondition(auto result = return, result == 1) ) { return 2; // obviously wrong } DLL_MODE void test_contracts() { int i = give1(); } ==================================== EXE: ==================================== # include <contract.hpp> # include "../testdll/testdll.h" void PostconditionHandler( contract::from const& context ) { std::cerr << "ERROR!!!" << std::endl; } int main() { contract::set_postcondition_broken(&PostconditionHandler); test_contracts(); } ==================================== I expect that the program would use the broken postcondition handler I installed, but it still uses the default one. The cause is that Contract is using some global object to store the installed handler, but when a program is linked with a DLL both the program and the DLL store their own copy of the global. The global is duplicated. THe one in the EXE registers my callback, but the global in the DLL still keeps the default handler. The only way to solve this issue is to -- at least in the cases when users' programs link with DLLs -- ship Contract with a small DLL that stores the unique copy of the globals. This is how Boost.Log handles this problem. Quoting the documentation ( http://boost-log.sourceforge.net/libs/log/doc/html/log/installation.html): *"If your application consists of more than one module (e.g. an exe and one or several dll's) that use Boost.Log, the library must be built as a shared object. If you have a single executable, you may build the library as a static library." * Regards, &rzej* *