views:

1482

answers:

10
+6  Q: 

C/C++ goto

Hi everybody!

I want to declare an array of "jumplabels". Then I want to jump to a "jumplabel" in this array. But I have not any idea how to do this. It should look like the following code:

function()
{
    "gotolabel" s[3];
    s[0] = s0;
    s[1] = s1;
    s[2] = s2;

    s0:
    ....
    goto s[v];

    s1:
    ....
    goto s[v];

    s2:
    ....
    goto s[v];
}

Does anyone have a idea how to perform this? Sorry for my bad English! Thanks for your help!

+6  A: 

There's no direct way to store code addresses to jump to in C. How about using switch.

#define jump(x)  do{ label=x; goto jump_target; }while(0)
int label=START;
jump_target:
switch(label)
{
    case START:
     /* ... */
    case LABEL_A:
     /* ... */
}

You can find similar code produced by every stack-less parser / state machine generator. Such code is not easy to follow so unless it is generated code or your problem is most easily described by state machine I would recommend not do this.

lispmachine
I think you want to drop the `goto` in front of the label `jump_target`
Christoph
right, fixed now
lispmachine
+6  A: 

could you use function pointers instead of goto?

That way you can create an array of functions to call and call the appropriate one.

rikh
I know that it can me made with function pointers. But this would be slow, because I would have to call a function to often. I think the call-overhead would be to big!
@youllknow: The words "I think" in the above comment tell me that you're in real danger of falling for "premature optimization". The first goal should be to start with a clear "working" solution and then optimize it as necessary. Consider this: only 1 compiler has this feature as an extension, however, every C/C++ compiler uses state machines. If this is the best way to go about solving this problem, why doesn't every compiler have this feature?
Richard Corden
@Richard Corden: So you think the speed improvment is very low? I thought about the function pointer array as well. The problem is the functions would be called very often, but they do only little things. So I thought that calling the funtion might be more expensive than what the function does. I am able to implement my problem with function pointers, but I thought that I can speed it up with the "goto-method". What's your opionion?
@youllknow: A function call is very cheap: it's not much more expensive than a goto and has far fewer problems. Remember that the compiler is always better than you at optimizing.
greyfade
@youllknow: There is going to be a performance difference, but you need to keep in mind the trade off between "clarity" and "performance". If it were me, my first "performance" tweak would be to see can I use some combination of templates + inline functions and so allow the compiler to optimize as much as possible. BTW, this may already exist in the boost spirit library: http://www.boost.org/doc/libs/1_39_0/libs/statechart/doc/index.html.
Richard Corden
+3  A: 

In plain standard C, this not possible as far as I know. There is however an extension in the GCC compiler, documented here, that makes this possible.

The extension introduces the new operator &&, to take the address of a label, which can then be used with the goto statement.

unwind
Interesting, didn't know that. Thanks.
Subtwo
yes, very nice!, thanks!
+13  A: 

goto needs a compile-time label.

From this example it seems that you are implementing some kind of state machine. Most commonly they are implemented as a switch-case construct:

while (!finished) switch (state) {
  case s0:
  /* ... */
  state = newstate;
  break;

  /* ... */
}

If you need it to be more dynamic, use an array of function pointers.

laalto
+4  A: 

That's what switch statements are for.

switch (var)
{
case 0:
    /* ... */
    break;
case 1:
    /* ... */
    break;
default:
    /* ... */
    break;  /* not necessary here */
}

Note that it's not necessarily translated into a jump table by the compiler.

If you really want to build the jump table yourself, you could use a function pointers array.

Bastien Léonard
It was only an simple example...In my option switch is to slow if I have 2^16 cases?Isn't it?
@youllknow: often good compilers will optimize a dense switch into a jump table for you. So no, switches aren't necessarily slow.
+2  A: 

You can't do it with a goto - the labels have to be identifiers, not variables or constants. I can't see why you would not want to use a switch here - it will likely be just as efficient, if that is what is concerning you.

anon
Yes, it's all about speed!Is it even likely just as fast if there are 2^16 cases?
@youllknow: a switch should be as fast as a computed goto, as the compiler should create a jump table as well
Christoph
If youllknow really wants to have 65K jump targets I wouldn't be surprised if most compilers would fall over trying to compile a switch with that many cases.
Michael Burr
+4  A: 

For a simple answer, instead of forcing compilers to do real stupid stuff, learn good programming practices.

BubbaT
Without knowing the context how can you judge this as "real stupid stuff"? Blindly following rules (such as "goto is evil") is good for beginners. Experienced programmers know where to make an exception.
lispmachine
After consideration it's unlikely that experienced programmer would ask such question but this is impolite to prejudge.
lispmachine
it is used for a tokenizer
+22  A: 

It is possible with GCC feature known as "labels as values".

void *s[3] = {&&s0, &&s1, &&s2};

if (n >= 0 && n <=2)
    goto *s[n];

s0:
...
s1:
...
s2:
...

It works only with GCC!

qrdl
thank!this is exactly what I wanted to know!
if this is the right answer, mark it as an answer !
Bluebird75
+1 for exposing weirdness (blech, gack, yuck!)
Jason S
ahhhh gcc, if only you could be in Visual Studio too!
toto
It is possible to change what compiler visual studio calls...
Rob K
+2  A: 

You might want to look at setjmp/longjmp.

Paul Mitchell
+1  A: 

Tokenizer? This looks like what gperf was made for. No really, take a look at it.

Thomas