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];
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.