问题与longjmp

我想使用longjmp来模拟goto指令。我有一个包含struct类型元素的数组DS(int,float,bool,char)。我想跳到标有“lablex”的地方,其中x是DS [TOP] .int_val。我怎么处理这个? 示例代码:
...
jmp_buf *bfj;
...
stringstream s;s<<"label"<<DS[TOP].int_val;
bfj = (jmp_buf *) s.str();
longjmp(*bfj,1);
但是我认为它有问题我该怎么办? 错误: output.cpp:在函数'int main()'中: output.cpp:101:错误:从类型'std :: basic_string,std :: allocator>'转换为无效的类型'__jmp_buf_tag(*)[1]'     
已邀请:
你可能根本不想使用longjmp,但是当人们回答“你为什么要这样做?”的问题时我讨厌它。正如已经指出你的longjmp()用法是错误的。这是一个如何正确使用它的简单示例:
#include <setjmp.h>

#include <iostream>

using namespace std;

jmp_buf jumpBuffer;  // Declared globally but could also be in a class.

void a(int count) {
  // . . .
  cout << "In a(" << count << ") before jump" << endl;
  // Calling longjmp() here is OK because it is above setjmp() on the call
  //   stack.
  longjmp(jumpBuffer, count);  // setjump() will return count
  // . . .
}


void b() {
  int count = 0;

  cout << "Setting jump point" << endl;
  if (setjmp(jumpBuffer) == 9) return;
  cout << "After jump point" << endl;

  a(count++);  // This will loop 10 times.
}


int main(int argc, char *argv[]) {
  b();

  // Note: You cannot call longjmp() here because it is below the setjmp() call
  //  on the call stack.

  return 0;
}
您使用longjmp()的问题如下: 你不要调用setjmp() 您尚未在堆栈上或动态分配jmp_buf。 jmp_buf * bfj只是一个指针。 你不能将char *转换为jmp_buf *并期望它能够工作。 C ++不是静态编译的动态语言。 但实际上,你根本不可能使用longjmp()。     
使用longjump的常规方法是与setjump()组合,如此处所述。您似乎想像通常使用switch-case或虚函数一样进行跳转。 无论如何,代码(编译时)中的标签不能用字符串(运行时)访问,所以这已经是你的第一个问题了。你真的需要找到你想要跳转到的地址,我最好的猜测是将setjump()放在你的标签所在的位置。     
你完全失败的C ++。首先,goto是坏的,而不是没有经验的 - 有一个原因,因为,while,break,continue等存在。其次,您正在尝试将字符串转换为标识符,这在运行时是不可能的,除非您自己编写代码。第三,你是......试图将一个const char *转换为jmp_buf *?什么? 除此之外,C ++确实有goto。但是如果你想跳转给定一个int,那么你将不得不切换它,例如
switch (DS[TOP].int_val) {
case 1:
    goto label1;
    break;
case 2:
    goto label2;
    break;
default:
    throw std::runtime_error("Unrecognized label!");
}
    
听起来像你想要一个函数指针:
((void(*)(void))*((int *)DS[TOP].int_val))();
这会将DS [TOP] .int_value视为一个地址并跳转到它。如果你想跳到DS [TOP] .int_value所在的位置,你会:
((void(*)(void))*((int *)&DS[TOP].int_val))();
无论哪种方式,丑陋,丑陋的代码。但它应该做你想要的。     
调用setjmp()时,系统会有效地获取调用和参数堆栈的快照。在用户代码退出调用setjmp()的块之前,此快照将保持有效;如果使用该快照调用longjmp(),则执行将恢复,就像setjmp()第一次返回一样,除了不返回零,它将返回传递给longjmp()的第二个参数。请注意,使用无效快照调用longjmp()可能会产生非常糟糕的影响,这一点非常重要。在某些系统中,这样的无效调用可能“似乎”起作用,但会以稍后崩溃的方式破坏系统。 虽然setjmp()/ longjmp()有时适用于纯C程序,但让C程序调用setjmp()来创建快照,然后调用一些C ++代码,然后再调用longjmp()来返回该快照,灾难的秘诀。几乎所有人都希望这样做的情况可以使用异常更好地处理。     

要回复问题请先登录注册