6.2 Locally Declared Labels

GCC allows you to declare local labels in any nested block scope. A local label is just like an ordinary label, but you can only reference it (with a goto statement, or by taking its address) within the block in which it is declared.

A local label declaration looks like this:

     __label__ label
;

or

     __label__ label1
, label2
, /* ...
 */;

Local label declarations must come at the beginning of the block, before any ordinary declarations or statements.

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 for complex macros. If a 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 is multiply defined in that function. A local label avoids this problem. For example:

     #define SEARCH(value, array, target)              \
     do {                                              \
       __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:;                                          \
     } while (0)

This could also be written using a statement expression:

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

Local label declarations also make the labels they declare visible to nested functions, if there are any. See Nested Functions , for details.