Each statement expression is a scope in which local labels can be
declared. A local label is simply an identifier; you can jump to it
with an ordinary goto
statement, but only from within the
statement expression it belongs to.
A local label declaration looks like this:
__label__ label;
or
__label__ label1, label2, /* ... */;
Local label declarations must come at the beginning of the statement
expression, right after the ({
, before any ordinary
declarations.
The label declaration defines the label name, but does not define
the label itself. You must do this in the usual way, with
label
:
, within the statements of the statement expression.
The local label feature is useful because statement expressions are
often used in macros. If the macro contains nested loops, a goto
can be useful for breaking out of them. However, an ordinary label
whose scope is the whole function cannot be used: if the macro can be
expanded several times in one function, the label will be multiply
defined in that function. A local label avoids this problem. For
example:
#define SEARCH(array, target) \ ({ \ __label__ found; \ typeof (target) _SEARCH_target = (target); \ typeof (*(array)) *_SEARCH_array = (array); \ int i, j; \ int value; \ for (i = 0; i < max; i++) \ for (j = 0; j < max; j++) \ if (_SEARCH_array[i][j] == _SEARCH_target) \ { value = i; goto found; } \ value = -1; \ found: \ value; \ })