вторник, октября 17, 2006

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. Спасибо.

Комментариев нет: