#include <iostream> #include <setjmp.h> #include <string> #include <string.h> #include <thread> #include <stdio.h> char* str[3] = {}; void outputstri(int idx) { std::cout << "str[" << idx << "] now is " << str + idx << ": " << str[idx][0] << str[idx][1] << str[idx][2] << str[idx][3] << str[idx][4] << str[idx][5] << str[idx][6] << str[idx][7] << str[idx][8] << str[idx][9] << std::endl; } class clsinfo { public: clsinfo(int idx) :m_idx_(idx) { m_s_ = new char[idx+5]; memset(m_s_,'A'+idx,idx+5*sizeof(char)); str[idx] = m_s_; outputstri(idx); std::cout << "begin(" << m_idx_ << ")."<<std::endl; } ~clsinfo() { delete[] m_s_; std::cout << "end(" << m_idx_ << ")." << std::endl; } private: int m_idx_; char *m_s_; }; jmp_buf jmpenv; void my_jmp_func() { clsinfo i(2); for (int i = 0; i < 4; ++i) { std::cout<<"my_jmp_func running("<<i<<")..."<<std::endl; std::this_thread::sleep_for(std::chrono::milliseconds(200)); } longjmp(jmpenv,1); } int main() { { clsinfo i(0); if (setjmp(jmpenv) == 0) { clsinfo i(1); my_jmp_func(); } } outputstri(0); outputstri(1); outputstri(2); return 1; }
这段代码在windows上vs2013编译运行结果为:
在linux上编译运行结果为:
gcc版本为:
可以看出在vs编译的版本中,虽然longjmp跳转与常规的函数调用堆栈处理方式不同,但依然保证了类对象在离开作用域时被析构,而gcc好像没有保证,所以raii方式的资源管理在这时会出问题。
还有当程序有处理信号(singal)时也会存在这种情况,但是goto不会有这种情况发生。