youllknow
youllknow

Reputation:

How to store goto labels in an array and then jump to them?

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?

Upvotes: 25

Views: 12867

Answers (11)

Damnatio Memoriae
Damnatio Memoriae

Reputation: 11

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.

Upvotes: 1

lispmachine
lispmachine

Reputation: 4526

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.

Upvotes: 12

Thomas
Thomas

Reputation: 4255

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

Upvotes: 1

Paul Mitchell
Paul Mitchell

Reputation: 3281

You might want to look at setjmp/longjmp.

Upvotes: 4

qrdl
qrdl

Reputation: 35008

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!

Upvotes: 46

BubbaT
BubbaT

Reputation: 1840

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

Upvotes: 1

anon
anon

Reputation:

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.

Upvotes: 2

Bastien L&#233;onard
Bastien L&#233;onard

Reputation: 61833

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.

Upvotes: 5

laalto
laalto

Reputation: 152927

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.

Upvotes: 17

unwind
unwind

Reputation: 400159

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.

Upvotes: 6

Rik Heywood
Rik Heywood

Reputation: 13972

could you use function pointers instead of goto?

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

Upvotes: 8

Related Questions