Next: , Previous: , Up: Statements   [Contents][Index]


19.13 Locally Declared Labels

In GNU C you can declare local labels in any nested block scope. A local label is used in a goto statement just like an ordinary label, but you can only reference it within the block in which it was 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 declares the label name, but does not define the label itself. That’s done in the usual way, with label:, before one of the statements in the block.

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 will be multiply defined in that function. A local label avoids this problem. For example:

#define SEARCH(value, array, target)              \
do {                                              \
  __label__ found;                                \
  __auto_type _SEARCH_target = (target);          \
  __auto_type _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 (see Statement Exprs):

#define SEARCH(array, target)                     \
({                                                \
  __label__ found;                                \
  __auto_type _SEARCH_target = (target);      \
  __auto_type _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;                                          \
})

Ordinary labels are visible throughout the function where they are defined, and only in that function. However, explicitly declared local labels of a block are visible in nested functions declared within that block. See Nested Functions, for details.

See goto Statement.


Next: , Previous: , Up: Statements   [Contents][Index]