3

我正在为 C++ 库编写一个 PERL XS 接口。croak当库抛出异常时我需要调用。

直接在异常处理程序中执行它会错过对捕获异常的析构函数的调用,正如longjmp调用所期望的那样。这很重要,因为异常包含不会被释放的字符串成员。

显而易见的解决方案是croak在 catch 块之后执行,如果捕获到异常,如下所示:

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);
}
4

1 回答 1

4

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

C++11 18.10/4:如果将and替换为,则setjmp/longjmp调用对具有未定义的行为,并且将为任何自动对象调用任何非平凡的析构函数。setjmplongjmpcatchthrow

在这种情况下,抛出异常 fromcroak将调用 的析构函数e,因此longjmp从那里调用会产生未定义的行为。自己调用析构函数只会使行为更不明确。

于 2013-03-28T16:37:02.433 回答