Next:Nested Functions, Previous:Locally Declared Labels, Up:Other Extensions to C Syntax [Contents][Index]
You can get the address of a label defined in the current function(or a containing function) with the unary operator ‘&&’. Thevalue has typevoid *. This value is a constant and can be usedwherever 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 donewith the computed goto statement6,goto *exp;. For example,
goto *ptr;
Any expression of typevoid * is allowed.
One way of using these constants is in initializing a static array thatserves as a jump table:
static void *array[] = { &&foo, &&bar, &&hack };Then you can select a label with indexing, like this:
goto *array[i];
Note that this does not check whether the subscript is in bounds—arrayindexing in C never does that.
Such an array of label values serves a purpose much like that of theswitch statement. Theswitch statement is cleaner, souse that rather than an array unless the problem does not fit aswitch statement very well.
Another use of label values is in an interpreter for threaded code.The labels within the interpreter function can be stored in thethreaded code for super-fast dispatching.
You may not use this mechanism to jump to code in a different function.If you do that, totally unpredictable things happen. The best way toavoid this is to store the label address only in automatic variables andnever pass it as an argument.
An alternate way to write the above example is
static const int array[] = { &&foo - &&foo, &&bar - &&foo, &&hack - &&foo };goto *(&&foo + array[i]);This is more friendly to code living in shared libraries, as it reducesthe number of dynamic relocations that are needed, and by consequence,allows the data to be read-only.This alternative with label differences is not supported for the AVR target,please use the first approach for AVR programs.
The&&foo expressions for the same label might have differentvalues if the containing function is inlined or cloned. If a programrelies on them being always the same,__attribute__((__noinline__,__noclone__)) should be used toprevent inlining and cloning. If&&foo is used in a staticvariable initializer, inlining and cloning is forbidden.
Unlike a normal goto, in GNU C++ a computed goto will not calldestructors for objects that go out of scope.
The analogous feature inFortran is called an assigned goto, but that name seems inappropriate inC, where one can do more than simply store label addresses in labelvariables.
Next:Nested Functions, Previous:Locally Declared Labels, Up:Other Extensions to C Syntax [Contents][Index]