Я пишу интерфейс PERL XS для библиотеки C ++. Мне нужно позвонить 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);
}
Практически невозможно использовать longjmp
безопасно в программе на C ++. В частности:
С ++ 11 18.10 / 4: A
setjmp
/longjmp
Пара вызовов имеет неопределенное поведение при заменеsetjmp
а такжеlongjmp
отcatch
а такжеthrow
будет вызывать любые нетривиальные деструкторы для любых автоматических объектов.
В этом случае выдается исключение из croak
будет вызывать деструктор e
так зовет longjmp
оттуда даст неопределенное поведение. Вызов деструктора сам делает поведение еще менее определенным.
Других решений пока нет …