我正在为C ++库编写PERL XS接口。当库抛出异常时,我需要调用croak
。
直接在异常处理程序中执行它会错过对被捕获异常的析构函数的调用,正如longjmp
调用所期望的那样。这很重要,因为异常包含不会被释放的字符串成员。
显而易见的解决方案是在catch块之后执行croak
,如果发现了异常,就像这样:
bool do_croak = false;
try {
throw MyException();
} catch (MyException &e) {
do_croak = true;
}
if (do_croak)
croak(NULL);
但我想知道:在longjmp
之前显式调用被捕获的异常的析构函数是否足够?像这样:
try {
throw MyException();
} catch (MyException &e) {
e.~MyException();
croak(NULL);
}
答案 0 :(得分:3)
在C ++程序中安全使用longjmp
几乎是不可能的。具体做法是:
C ++ 11 18.10 / 4:如果将
setjmp
和longjmp
替换为setjmp
和{longjmp
/catch
调用对,则会有未定义的行为{1}}将为任何自动对象调用任何非平凡的析构函数。
在这种情况下,从throw
抛出异常会调用croak
的析构函数,因此从那里调用e
会给出未定义的行为。自己调用析构函数只会使行为定义得更少。