Анализатор Expat - С++ - Обработка исключений

Я зарегистрировал три обработчика с парсером expat: - start -end - text

И из основной программы я читаю файл xml, буферизирую его и вызываю API XML_Parse. Что-то вроде этого:

try {
if( ! XML_Parse (....))
{
   // throw user-defined expection here
}
catch(...)
{
}
} // end of try
catch(...)
{
 }

Если XML_Parse возвращает 0 в случае ошибки, это означает, что внутри if создается исключение. И он пойман во внутреннем блоке захвата.

Вот мой вопрос: если пользовательское исключение выдается из любого из обработчиков во время синтаксического анализа, будет ли оно перехвачено внешним уловом?

Если да, то на самом деле этого не происходит в моем коде. Вместо этого он сбрасывает ядро, и стек показывает, что throw приводит к std:terminate. Должен ли я выполнять что-либо еще, прежде чем создавать исключения из HANDLERS.

Спасибо.


person syed misba    schedule 27.10.2011    source источник


Ответы (3)


У вас есть несоответствие между try и catch: за каждым блоком try следует как минимум один блок catch, но у вас есть только один блок try. Может быть так:

try
{
  // stuff before

  try
  {
    if (!parse())
    {
      // ...
    }
  }

  // further catch blocks?

  catch(...)
  {
    // may rethrow
  }

  // stuff after
}

Обратите внимание, что анонимный catch(...) обычно не очень хороший дизайн — вы либо знаете, чего ожидаете, и можете с этим справиться, либо вам не нужно его улавливать. Единственная полезная вещь для анонимного улова — это зарегистрировать исключение и повторно выдать его.

person Kerrek SB    schedule 27.10.2011
comment
Мне жаль. Внутреннего улова нет. Есть только одна загвоздка, которая следует за попыткой. Итак, есть два места, откуда могут быть выброшены исключения. Один изнутри if, а другой от любого из HANDLERS. Итак, как он ведет себя, когда исключение генерируется из HANDLERS? - person syed misba; 27.10.2011
comment
И более того, анонимный улов — это просто описание проблемы. У меня есть правильные блоки catch, обрабатывающие брошенные объекты. Меня больше всего беспокоит, что произойдет, если HANDLERS генерируют исключения? - person syed misba; 27.10.2011

Если вы создаете исключение из блока try{/*stuff*/}, а блок throw глубоко вложен, стек раскручивается до соответствующей внешней функции catch(...). Если ваши обработчики выделили динамическую память, вам нужно будет решить эту проблему либо с помощью shared_ptr<>, либо явным и осторожным удалением. Если ваши обработчики находились внутри блока try, то исключение должно вести себя как обычно.

person Philip Langford    schedule 27.10.2011

Вы должны быть очень осторожны с этим. (Из-за этого было очень трудно отследить проблемы в коде, над которым я работал.). В моем случае библиотеки expat, которые мне пришлось использовать, не были созданы с использованием необходимых флагов исключений в gcc, и, поскольку expat — это C (а не C++), он не знал, что делать с исключениями — когда они возникали, приложение просто завершалось. .

Однако, если вы можете собрать expat с правильными флагами gcc, все должно быть в порядке. (Пересборка expat для меня была невозможна, поэтому вместо этого я переключился на синтаксический анализ DOM с использованием libxml2).

person Michael Anderson    schedule 27.10.2011