如下代码:

  • 使用gcc版本4.4.5(Ubuntu/Linaro 4.4.4-14ubuntu5/32bits)编译时运行良好
  • 与MSVC10(Win7/32bits)一起编译时运行良好
  • 使用gcc版本4.5.2(在Win7/32bits上为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 ;
        }
    }
    

    我尝试调试它,但是该程序的行为异常。有时我可以越过第一个断点(BP1),然后在BP2崩溃,并且有时控制永远无法到达BP1,就像程序陷入无限循环一样。我的调试技巧不能多说。

    这段代码是我得到的最少的代码,它表现出MinGW 4.5的奇怪行为。我还注意到:
  • 如果我用其内容替换do_work函数调用,则程序可以正常运行。
  • 如果删除try{ ... } catch(...){ }内的do_work块,则程序运行正常。
  • 优化标志无效(始终崩溃)。

  • 我知道C++代码中的setjmp/longjmp问题,但是我不得不使用它与某些旧版C代码进行接口(interface)。

    我的问题 :
  • 这是错误的/错误的/错误的代码吗?还是MinGW 4.5处理代码不正确? (责怪该工具既严厉又冒昧,但我怀疑其中有一些设置)。

  • 感谢您的任何建议。

    如有必要,请重新标记。

    最佳答案

    Unix上的longjmp(3)手册页显示:



    我认为这解释了您的担忧,即“有时控制永远无法达到BP1”。
    我认为“运转良好”不是可靠的判断。我宁愿期望它随机运行,并且通常会弄乱堆栈。

    在将longjmp/setjmp与C++异常混合使用时,应考虑一些明确的建议,以避免崩溃和不确定的行为:

  • 不要在C++程序中使用setjmp/longjmp。
  • 如果在程序中使用setjmp/longjmp函数,在这些函数中可能会发生异常,只要它们不相互作用,就可以保证安全。
  • 切勿在try子句和catch子句中使用longjmp。
  • 切勿在自动对象的初始化点上使用longjmp。
  • 永远不会破坏自动对象,特别是在析构函数很重要的情况下。
  • 切勿从信号处理程序中抛出。
  • 切勿从嵌套信号处理程序中调用longjmp。
  • 从位置X到位置Y的longjmp行为保持可预测和有效,只要在X处引发并在X处捕获的异常具有相同的效果即可。
  • 如果将setjmp/longjmp与异常(exception)混合使用,请不要期望可移植性。
  • 相反,请引用所用文档编译器中的相关详细信息。例如,如果您使用Visual C++,请阅读Use setjmp/longjmp

  • 这个问题提到在用C++编写的程序中处理旧版C代码。在审查Boost库之一的过程中,在jpeg库中对sjlj问题进行了有趣的讨论。讨论时间很长,但这里是essence with recommended options

    关于c++ - 此代码是否包含隐藏的错误?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7938835/

    10-13 05:11