13.3 Labels as Values

You can get the address of a label defined in the current function (or a containing function) with the unary operator '&&'. This is a non-standard extension to the language. Using this feature reduces your code portability.

The value returned has type void *. This value is a constant and can be used wherever a constant of that type is valid. For example:

void *ptr;
...
ptr = &&foo;

To use these values, you need to be able to jump to one. This is done with the computed goto statement, goto *exp;. For example:

goto *ptr;

Any expression of type void * is allowed.

One way of using these constants is in initializing a static array that will serve as a jump table:

static void *array[] = { &&foo, &&bar, &&hack };

Then you can select a label with indexing, like this:

goto *array[i];

Note: This does not check whether the subscript is in bounds. (Array indexing in C never does.)

Such an array of label values serves a purpose much like that of the switch statement. The switch statement is cleaner and therefore preferable to an array.

Another use of label values is in an interpreter for threaded code. The labels within the interpreter function can be stored in the threaded code for fast dispatching.

This mechanism can be misused to jump to code in a different function. The compiler cannot prevent this from happening, so care must be taken to ensure that target addresses are valid for the current function.