Question

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?

Was it helpful?

Solution

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!

OTHER TIPS

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.

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.

could you use function pointers instead of goto?

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

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.

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.

You might want to look at setjmp/longjmp.

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.

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

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

Optimizing compilers (including GCC) will compile a switch statement into a jump table (making a switch statement exactly as fast as the thing you're trying to construct) IF the following conditions are met:

Your switch cases (state numbers) start at zero.

Your switch cases are strictly increasing.

You don't skip any integers in your switch cases.

There are enough cases that a jump table is actually faster (a couple dozen compare-and-gotos in the checking-each-case method of dealing with switch statements is actually faster than a jump table.)

This has the advantage of allowing you to write your code in standard C instead of relying on a compiler extension. It will work just as fast in GCC. It will also work just as fast in most optimizing compilers (I know the Intel compiler does it; not sure about Microsoft stuff). And it will work, although slower, on any compiler.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top