这段代码是否包含隐藏的错误?

ove*_*der 6 c++ mingw setjmp

以下代码:

  • 使用gcc版本4.4.5(Ubuntu/Linaro 4.4.4-14ubuntu5/32bits)编译时运行正常
  • 使用MSVC10(Win7/32bits)编译时运行正常
  • 使用gcc版本4.5.2(Win7/32位上的MinGW)运行时崩溃

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 ;
    }
}
Run Code Online (Sandbox Code Playgroud)

我试过调试它,但程序行为奇怪.有时我可以通过第一个断点(BP1),然后在BP2崩溃,有时控制永远不会到达BP1,就像程序陷入无限循环一样.我的调试技巧不能多说.

这段代码是我能得到的最小的代码,展示了MinGW 4.5的奇怪行为.我也注意到:

  • 如果我用do_work其内容替换函数调用,程序运行正常.
  • 如果我删除try{ ... } catch(...){ }里面的块do_work,程序运行正常.
  • 优化标志无效(始终崩溃).

我知道setjmp/longjmpC++代码中的问题,但我不得不使用它来与一些遗留的C代码进行交互.

我的问题 :

  • 这是一个错误/错误/错误的代码?或者是MinGW 4.5错误处理代码?(责备这个工具是苛刻和冒昧的,但我怀疑它有一些设置).

谢谢你的建议.

如有必要,请重新登记.

Nec*_*lis 0

longjmpsetjmp是 c 函数,使用 C++ 异常处理语义和对象销毁语义调用它们是未定义的行为,这意味着它是否有效取决于实现(您的测试表明这一点,SEH 堆栈展开语义会破坏事物,具体取决于类型用过,iirc 你的工作人员正在使用 dwarf2)