Post

Dynamic jumps in C

Dynamic jumps in C

What are dynamic jumps?

Have you ever wanted to dynamically decide where your program jumps to while it is already running?

In C you normally use things like if, switch, goto, and loops. But GCC and Clang also support something much more unusual: computed gotos.

With computed gotos, we can take the address of a label, store it in a variable, and later jump to that address.

Getting the Address of a Label

Normally, goto works like this:

1
2
3
4
goto loop_one;

loop_one:
    // code

But GCC and Clang let us get the address of a label using &&:

1
2
3
4
void* loop_exec = &&loop_one;

loop_one:
    // code

Now loop_exec contains the address of loop_one.

We can execute the jump dynamically using:

1
goto *loop_exec;

Changing the Jump While Running

This becomes interesting when we change the jump target during execution.

For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void* loop_exec = &&loop_one;

loop_one:
    if (x) {
        check_something();
    } else {
        loop_exec = &&loop_two;
    }

    goto loop_two;

loop_two:
    do_something();
    goto *loop_exec;

At the beginning:

The program starts at loop_one.

If x is true, loop_exec is never changed:

1
loop_one -> loop_two -> loop_one -> loop_two

But if x becomes false:

we change the destination:

Now the execution becomes:

1
loop_one -> loop_two -> loop_two -> loop_two

This Isn’t Standard C

This:

1
&&label

and:

1
goto *pointer;

are compiler extensions, not part of ISO C.

This post is licensed under CC BY 4.0 by the author.