在longjmp / croak之前显式调用析构函数

时间:2013-03-28 16:30:25

标签: c++ perl longjmp

我正在为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);
}

1 个答案:

答案 0 :(得分:3)

在C ++程序中安全使用longjmp几乎是不可能的。具体做法是:

  

C ++ 11 18.10 / 4:如果将setjmplongjmp替换为setjmp和{longjmp / catch调用对,则会有未定义的行为{1}}将为任何自动对象调用任何非平凡的析构函数。

在这种情况下,从throw抛出异常会调用croak的析构函数,因此从那里调用e会给出未定义的行为。自己调用析构函数只会使行为定义得更少。