Ocaml exceptions & C++ destructors
Маленький совет для тех, кто пишет окемловкие байндинги к плюсовым библиотекам.
Никогда! Запомните! Никогда не мешайте окемловские эксепшны с плюсовыми объектами. Из-за longjmp(), который вызывается внутри caml_failwith, caml_invalid_argument или caml_raise*, ни один деструктор плюсового объекта не будет вызван и вы получите memory leak.
Также не мешайте обработку плюсовых эксепшнов и вызов окемловских эксепшнов, т.к. плюсовые эксепшны - это те же классы с деструкторами. Т.е. в данном коде
try
{
bla-bla;
throw std::runtime_error( "oh, shit!" );
}
catch ( std::runtime_error& e )
{
caml_failwith( e.what() );
}
деструктор std::runtime_error не будет вызван и строчка "oh, shit!" навсегда останется в памяти. gcc пофиг на __attribute__ ((noreturn)).
Объекты отдельно, failwith отдельно. Запомните это, пожалуйста, и тогда вам не придется две недели анализировать логи mtrace или valgrind. Спасибо.
Комментариев нет:
Отправить комментарий