Содержит ли этот код скрытую ошибку?

Следующий код:

  • Работает нормально при компиляции с gcc версии 4.4.5 (Ubuntu / Linaro 4.4.4- 14ubuntu5 / 32bits)
  • Работает нормально при компиляции с MSVC10 (Win7 / 32bits)
  • Сбои при работе с gcc версии 4.5.2 (MinGW на Win7 / 32bits)

main.cpp :

# include <iostream>
# include <csetjmp>
# include <stdexcept>

using namespace std ;

void do_work(jmp_buf context)
{
    try
    {
        throw runtime_error("Ouch !") ;
    }
    catch(exception & e)
    {
    }

    longjmp(context, -1) ;                        //BP1
}

int main(int, char *[])
{
    jmp_buf context ;

    try
    {
        if( setjmp(context) != 0 )
        {
            throw runtime_error("Oops !") ;       //BP2
        }

        do_work(context) ;
    }
    catch(exception & e)
    {
        cout << "Caught an exception saying : " << e.what() << endl ;
    }
}

Я пытался отладить его, но программа ведет себя странно. Иногда я мог пройти первую точку останова (BP1), затем сбой на BP2, а иногда управление никогда не достигало BP1, например, если программа застряла в бесконечном цикле. Я не могу сказать больше о моих навыках отладки.

Это минимальный код, который я смог получить, демонстрируя странное поведение с MinGW 4.5. Я также заметил, что:

  • Если я заменю вызов функции do_work ее содержимым, программа будет работать нормально.
  • Если я удалю блок try {...} catch (...) {} внутри do_work , программа будет работать нормально.
  • Флаги оптимизации не действуют (всегда происходит сбой).

Мне известно о проблемах setjmp / longjmp в коде C ++, но я вынужден использовать его для взаимодействия с некоторым устаревшим кодом C.

Мой вопрос:

  • Это неправильный / неверный код? Или MinGW 4.5 неправильно обрабатывает код? (Сурово и самонадеянно винить инструмент, но я подозреваю, что в нем есть какие-то настройки).

Спасибо за любой совет.

При необходимости измените теги.

6
задан overcoder 29 October 2011 в 12:14
поделиться