gcc: Local Labels

1 
1 6.2 Locally Declared Labels
1 ===========================
1 
1 GCC allows you to declare "local labels" in any nested block scope.  A
1 local label is just like an ordinary label, but you can only reference
1 it (with a 'goto' statement, or by taking its address) within the block
1 in which it is declared.
1 
1  A local label declaration looks like this:
1 
1      __label__ LABEL;
1 
1 or
1 
1      __label__ LABEL1, LABEL2, /* ... */;
1 
1  Local label declarations must come at the beginning of the block,
1 before any ordinary declarations or statements.
1 
1  The label declaration defines the label _name_, but does not define the
1 label itself.  You must do this in the usual way, with 'LABEL:', within
1 the statements of the statement expression.
1 
1  The local label feature is useful for complex macros.  If a macro
1 contains nested loops, a 'goto' can be useful for breaking out of them.
1 However, an ordinary label whose scope is the whole function cannot be
1 used: if the macro can be expanded several times in one function, the
1 label is multiply defined in that function.  A local label avoids this
1 problem.  For example:
1 
1      #define SEARCH(value, array, target)              \
1      do {                                              \
1        __label__ found;                                \
1        typeof (target) _SEARCH_target = (target);      \
1        typeof (*(array)) *_SEARCH_array = (array);     \
1        int i, j;                                       \
1        int value;                                      \
1        for (i = 0; i < max; i++)                       \
1          for (j = 0; j < max; j++)                     \
1            if (_SEARCH_array[i][j] == _SEARCH_target)  \
1              { (value) = i; goto found; }              \
1        (value) = -1;                                   \
1       found:;                                          \
1      } while (0)
1 
1  This could also be written using a statement expression:
1 
1      #define SEARCH(array, target)                     \
1      ({                                                \
1        __label__ found;                                \
1        typeof (target) _SEARCH_target = (target);      \
1        typeof (*(array)) *_SEARCH_array = (array);     \
1        int i, j;                                       \
1        int value;                                      \
1        for (i = 0; i < max; i++)                       \
1          for (j = 0; j < max; j++)                     \
1            if (_SEARCH_array[i][j] == _SEARCH_target)  \
1              { value = i; goto found; }                \
1        value = -1;                                     \
1       found:                                           \
1        value;                                          \
1      })
1 
1  Local label declarations also make the labels they declare visible to
1 nested functions, if there are any.  ⇒Nested Functions, for
1 details.
1