当前位置: 动力学知识库 > 问答 > 编程问答 >

How to (computed) goto and longjmp in C++?

问题描述:

I don't usually code C++, but a strange comp sci friend of mine got sick of looking at my wonderful FORTRAN programs and challenged me to rewrite one of them in C++, since he likes my C++ codes better. (We're betting money here.) Exact terms being that it needs to be compilable in a modern C++ compiler. Maybe he hates a good conio.h - I don't know.

Now I realize there are perfectly good ways of writing in C++, but I'm going for a personal win here by trying to make my C++ version as FORTRAN-esque as possible. For bonus points, this might save me some time and effort when I'm converting code.

SO! This brings me to the following related queries:

On gotos:

  1. How do you work a goto?
  2. What are the constraints on gotos in C++?
  3. Any concerns about scope? (I'm going to try to globally scope as much as possible, but you never know.)
  4. If I use the GCC extension to goto to a void pointer array, are there any new concerns about undefined behavior, etc?


On longjmp:

  1. How would you safely use a longjmp?
  2. What are the constraints on longjmps in C++?
  3. What does it do to scope?
  4. Are there any specific moments when it looks like a longjmp should be safe but in fact it isn't that I should watch out for?
  5. How would I simulate a computed goto with longjmp?
  6. Is there any tangible benefit to using longjmp over goto if I only have one function in my program?

Right now my main concern is making a computed goto work for this. It looks like I'll probably use the longjmp to make this work because a void pointer array isn't a part of the C++ standard but a GCC specific extension.

网友答案:

I'll bite and take the downvote.

I seriously doubt that your friend will find Fortran written in C++ any easier (which is effectively what you'll get if you use goto and longjmp significantly) to read and he might even find it harder to follow. The C++ language is rather different from Fortran and I really don't think you should attempt a straight conversion from Fortran to C++. It will just make the C++ harder to maintain and you might as well stay with your existing codebase.

goto: You set up a label (my_label:) and then use the goto command goto my_label; which will cause your program flow to execute at the statement following the goto. You can't jump past the initialization of a variable or between functions. You can't create an array of goto targets but you can create an array of object or function pointers to jump to.

longjmp: There is no reason to prefer longjmp over goto if you have only one function. But if you have only one function, again, you really aren't writing C++ and you'll be better off in the long run just maintaining your Fortran.

网友答案:

You'll get plenty of haterade about using goto at all. Normally I'd jump right on the bandwagon, but in this particular case it sounds more like code golf to me. So here you go.

Use goto to move the instruction pointer to a "label" in your code, which is a C++ identifier followed by a colon. Here's a simple example of a working program:

#include <iostream>
#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
    int i = 0;
step:
    cout << "i = " << i;
    ++i;
    if( i < 10 )
        goto step;

}

In this case, step: is the label.

There are concerns about context.

  • You can only goto to a label within the current function.
  • If your goto skips the initialization of a variable, you may evoke Undefined Behavior (Code which will compile, but you can't say for sure what it will actually do.).
  • You cannot goto in to a try block or catch handler. However, you can goto out of a try block.

You "can goto" with pointers etc provided the other concerns are met. If the pointer in question is in-scope at the call site and in-scope at the branch site, no problem.

网友答案:

I think this reference has most of the information you are looking for.

goto

longjmp

网友答案:

computed goto --> switch

Really, they share a (common, but not universal) underling implementation as a jump table.

网友答案:

If I understand the original question, the question is actually an interesting one. Rewording the question (to what I think is an equivalent question): "How do you do a FORTRAN computed goto in C?"

First we need to know what a computed goto is: Here is a link to one explanation: http://h21007.www2.hp.com/portal/download/files/unprot/fortran/docs/lrm/lrm0124.htm.

An example of a computed GOTO is:

    GO TO (12,24,36), INDEX

Where 12, 24, and 36 are statement numbers. (C language labels could serve as an equivalent, but is not the only thing that could be an equivalent.)

And where INDEX is a variable, but could be the result of a formula.

Here is one way (but not the only way) to do the same thing in C:

int SITU(int J, int K)
{
int raw_value = (J * 5) + K;

int index = (raw_value % 5) - 1;

return index;
}


int main(void)
{
int J = 5, K= 2;

// fortran computed goto statement: GO TO (320,330,340,350,360), SITU(J,K) + 1
switch (SITU(J,K) + 1)
{
case 0: // 320
    // code statement 320 goes here
    printf("Statement 320");
    break;
case 1: // 330
    // code statement 330 goes here
    printf("Statement 330");
    break;
case 2: // 340
    // code statement 340 goes here
    printf("Statement 340");
    break;
case 3: // 350
    // code statement 350 goes here
    printf("Statement 350");
    break;
case 4: // 360
    // code statement 360 goes here
    printf("Statement 360");
    break;
}

printf("\nPress Enter\n");
getchar();
return 0;
}

In this particular example, we see that you do not need C gotos to implement a FORTRAN computed goto!

网友答案:

Longjmp can get you out of a signal handler which can be nice - and it'll add some confusion as it will not reset automatic (stack-based) variables in the function it long jumps to defined prior to the setjmp line. :)

网友答案:

There is a GCC extension called Labels as Values that will help you code golf, essentially giving you computed goto. You can generate the labels automatically, of course. You will probably need to do that since you can't know how many bytes of machine code each line will generate.

分享给朋友:
您可能感兴趣的文章:
随机阅读: