6.3 Labels as values
You can get the address of the label defined in the current function (or containing the function) with the unary operator ' && . The value is of type void * . This value is a constant and can be used wherever a constant of this type acts. For instance:
void *ptr; ptr = &&foo;
To use these values, you must be able to switch to one. This is done with the computed operation goto 1 goto *exp; . For instance,
goto *ptr;
Any expression of type void * allowed.
One way to use these constants is to initialize a static array, which serves as a jump table:
static void *array[] = { &&foo, &&bar, &&hack };
Then you can select a label with indexing, for example:
goto *array[i];
Note that this does not check if the index is indexed in the array indexing method in C, never does it.
Such an array of label values serves a purpose similar to that of the switch statement. The switch statement is cleaner, so use it, not an array, if the problem is not very good for the switch statement.
Another use of label values in the interpreter is for multi-threaded code. Labels inside the interpreter function can be stored in stream code for ultra-fast dispatch.
You cannot use this mechanism to jump to code in another function. If you do this, completely unpredictable things will happen. The best way to avoid this is to save the label address in automatic variables only and never pass it as an argument.
An alternative way to write the above example is
static const int array[] = { &&foo - &&foo, &&bar - &&foo, &&hack - &&foo }; goto *(&&foo + array[i]);
This is more convenient for code living in shared libraries, because it reduces the number of necessary dynamic movements and, therefore, allows data to be read-only.
The &&foo expressions for the same label can have different meanings if the containing function is inline or cloned. If the program relies on the fact that they are always the same, __attribute__((__noinline__, __noclone__)) should be used to prevent embedding and cloning. If &&foo used in a static variable initializer, embedding and cloning is prohibited.
Footnotes[1] A similar function in Fortran is called the assigned goto, but that name seems unacceptable in C, where you can do more than just store label addresses in label variables.
Under no circumstances should this be taken as a recommendation to use this feature. The calculated goto been removed from Fortran; it’s better to leave it in the history bin.