Contents|Index|Previous|Next

Locally Declared Labels

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 __label__ label or __label__ label1, label2 and so on.

Local label declarations must come at the beginning of the statement expression, right after the parenthesis and brace, ‘({‘, 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. Use the following example, for instance.

    #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;                                        \
    })