Парсер экспатов - c ++ -обработка исключений - PullRequest
1 голос
/ 27 октября 2011

Я зарегистрировал три обработчика с парсером 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.

Спасибо.

Ответы [ 3 ]

0 голосов
/ 27 октября 2011

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

0 голосов
/ 27 октября 2011

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

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

0 голосов
/ 27 октября 2011

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

try
{
  // stuff before

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

  // further catch blocks?

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

  // stuff after
}

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

...