For unit testing one can substitute abort() and longjmp() from there, or when testing via C++ throwing from there.
For example (expressed as C++):
#include <cassert>
#include <csetjmp>
#include <stdexcept>
#include <iostream>
#ifndef lest_ABORT_SIGNATURE
# if _MSC_VER
# define lest_NORETURN __declspec(noreturn)
# define lest_ABORT_SIGNATURE() _ACRTIMP lest_NORETURN void __cdecl abort(void)
# else
# define lest_NORETURN [[noreturn]]
# define lest_ABORT_SIGNATURE() lest_NORETURN void __cdecl abort()
# endif
#else
# ifndef lest_NORETURN
# define lest_NORETURN
# endif
#endif
#if USE_LONGJMP
jmp_buf env;
lest_ABORT_SIGNATURE()
{
std::longjmp( env, 1 );
}
#else
struct Abort{};
lest_NORETURN void my_abort()
{
throw Abort{};
}
lest_ABORT_SIGNATURE()
{
// throw indirectly and prevent warning in VC14:
my_abort();
}
#endif
int main()
{
#if USE_LONGJMP
if ( ! setjmp( env ) )
{
std::cout << "assert(false):\n";
assert( false );
}
else
{
std::cout << "Intercepted abort\n";
}
#else
try
{
std::cout << "assert(false):\n";
assert( false );
}
catch ( Abort const & )
{
std::cout << "Caught Abort\n";
}
catch ( std::exception const & e )
{
std::cout << "Exception: " << e.what() << "\n";
}
#endif
std::cout << "End\n";
}
#if 0
cl -EHsc -DUSE_LONGJMP=1 abort-own.cpp && abort-own.exe
g++ -Wall -DUSE_LONGJMP=1 -std=c++11 -o abort-own.exe abort-own.cpp && abort-own.exe
#endif
Compiling with VC14 (VS2015) and runnning with:
cl -EHsc -DUSE_LONGJMP=1 abort-own.cpp && abort-own.exe
yields the following output:
...
assert(false):
Assertion failed: false, file abort-own.cpp, line 45
Intercepted abort
End
Compiling with a pre-VC14 compiler produces a link error:
LIBCMT.lib(abort.obj) : error LNK2005: _abort already defined in {file}
{exe} : fatal error LNK1169: one or more multiply defined symbols found
This may be cured by:
Compiling via g++ using -std=c++03
or -std=c++11
does not lead to a multiply defined symbol.
More elaborate versions of the code above I'm developing for the lest test framework: