开发者

question with longjmp

I want to use longjmp to simulate goto instruction.I have an array DS containing elements of st开发者_高级运维ruct types (int , float, bool ,char). I want to jump to the place labled "lablex" where x is DS[TOP].int_val. how can I handle this?

sample code :

...
jmp_buf *bfj;
...
stringstream s;s<<"label"<<DS[TOP].int_val;
bfj = (jmp_buf *) s.str();
longjmp(*bfj,1);

but as I thought it's having problem what should I do?

error:

output.cpp: In function ‘int main()’:

output.cpp:101: error: invalid cast from type ‘std::basic_string, std::allocator >’ to type ‘__jmp_buf_tag (*)[1]’


You probably don't want to use longjmp at all but I hate it when people answer a question with "Why would you want to do that?" As has been pointed out your longjmp() usage is wrong. Here is a simple example of how to use it correctly:

#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;
}

The problems with your usage of longjmp() are as follows:

  1. You don't call setjmp()
  2. You haven't allocated the jmp_buf either on the stack or dynamically. jmp_buf *bfj is just a pointer.
  3. You cannot cast a char * to jmp_buf * and expect it to work. C++ not a dynamic language it is statically compiled.

But really, it is very unlikely that you should be using longjmp() at all.


The normal way to use longjump is incombination with setjump() as described here. You seem to want to make a jumptable as normally done with switch-case or with virtual functions.

Anyway, labels in code (compile-time) are not reachable with strings (run-time), so that is already your first problem. You would really need to find out the address of where you want to jump to and my best guess would be to put setjump()'s where your labels are.


You've totally failed C++. Firstly, goto's are bad, and not for the uninitiated- there's a reason that for, while, break, continue etc exist. Secondly, you're trying to convert a string into an identifier, which is impossible at runtime unless you code it yourself. Thirdly, you're.. trying to cast a const char* to a jmp_buf*? What?

In addition to that, C++ does have goto. But if you want to jump given an int, then you're going to have to switch it, e.g.

switch (DS[TOP].int_val) {
case 1:
    goto label1;
    break;
case 2:
    goto label2;
    break;
default:
    throw std::runtime_error("Unrecognized label!");
}


Sounds like you want a function pointer:


((void(*)(void))*((int *)DS[TOP].int_val))();

This treats DS[TOP].int_value like an address and jumps to it. If you wanted to jump to where DS[TOP].int_value is located, you would:


((void(*)(void))*((int *)&DS[TOP].int_val))();

Either way, ugly, ugly code. But it should do what you want.


When setjmp() is called, the system effectively takes a snapshot of the call and parameter stack. This snapshot will remain valid until user code exits the block in which setjmp() was called; if longjmp() is called with that snapshot, execution will resume as though the setjmp() were returning for the first time, except that instead of returning zero, it will return the second parameter passed to longjmp(). It is very important to note that calling longjmp() with an invalid snapshot may have very bad effects. In some systems, such an invalid call may "seem" to work, but corrupt the system in such a way that it later crashes.

Although setjmp()/longjmp() are sometimes appropriate in pure C programs, having a C program call setjmp() to create a snapshot, and then call some C++ code which in turn calls longjmp() to return to that snapshot, is a recipe for disaster. Nearly all situations where one would want to do that may be better handled using exceptions.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜