Question

I'm writing a PERL XS interface to a C++ library. I need to call croak when the library throws an exception.

Doing it directly in the exception handler misses the call to the caught exception's destructor, as expected of a longjmp call. This is important, because the exception contains string members which won't get freed.

The obvious solution is to do the croak after the catch block, if an exception was caught, like this:

bool do_croak = false;
try {
    throw MyException();
} catch (MyException &e) {
    do_croak = true;
}
if (do_croak)
    croak(NULL);

But I'm wondering: Would it be enough to just explicitly call the caught exception's destructor just before the longjmp? Like this:

try {
    throw MyException();
} catch (MyException &e) {
    e.~MyException();
    croak(NULL);
}
Was it helpful?

Solution

It's almost impossible to use longjmp safely in a C++ program. Specifically:

C++11 18.10/4: A setjmp/longjmp call pair has undefined behavior if replacing the setjmp and longjmp by catch and throw would invoke any non-trivial destructors for any automatic objects.

In this case, throwing an exception from croak would invoke the destructor of e, so calling longjmp from there would give undefined behaviour. Calling the destructor yourself just makes the behaviour even less defined.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top