You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中setjmp/longjmp是否为未定义行为?Intel编译器析构函数重复调用疑问

这段C++代码是否触发未定义行为?
#include <iostream>
#include <csetjmp>

jmp_buf buffer1;
jmp_buf buffer2;

class Test
{
    public:
        ~Test()
        {
            std::cout << "Test destructor: " << this << std::endl;
        }
};

void p2()
{
    longjmp( buffer2, 1 );
}

void p1()
{
    {
        Test test;

        if ( setjmp( buffer2 ) == 0 )
        {
            p2();
        }
    }

    std::cout << "Jumping" << std::endl;
    longjmp( buffer1, 1 );
}

int main()
{
   if ( setjmp( buffer1 ) == 0 )
   {
       p1();
   }

   return 0;
}

在Windows平台使用Intel编译器编译运行上述代码时,Test类的析构函数会被调用两次。我将此问题上报为编译器bug,但Intel开发者认为这属于未定义行为,相关讨论在Intel开发者社区中进行。测试过的其他编译器均符合预期(仅调用一次析构函数)。

C++标准相关规定:

若将std::longjmp替换为throw,setjmp替换为catch会导致任何自动对象调用非平凡析构函数,则该std::longjmp的行为未定义。

但标准并未明确对应try块的位置:即当Test对象声明在setjmp之前时,是否属于“会导致自动对象调用非平凡析构函数”的情况。我认为setjmp之前没有代码会跳转至此,逻辑上对应的try块应该从setjmp开始,因此不应触发未定义行为,但标准对此没有明确说明,特此询问这段代码是否真的属于未定义行为?

内容的提问来源于stack exchange,提问作者dohashi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 20:44:55