Spec-Zone.ru › GCC 8

6.2 Локально объявленные метки

GCC позволяет объявлять локальные метки в любом вложенном блоке области видимости. Локальная метка ведет себя как обычная метка, но к ней можно обращаться (с помощью оператора goto или взятия ее адреса) только внутри блока, в котором она объявлена.

Объявление локальной метки выглядит следующим образом:

__label__ label;

или

__label__ label1, label2, /* … */;

Объявления локальных меток должны располагаться в начале блока, перед любыми обычными объявлениями или операторами.

Объявление метки определяет имя метки, но не саму метку. Сделать это нужно обычным способом, с помощью label:, внутри операторов выражения оператора.

Функция локальных меток полезна для сложных макросов. Если макрос содержит вложенные циклы, оператор goto может быть полезен для выхода из них. Однако обычная метка, область видимости которой охватывает всю функцию, использовать нельзя: если макрос может быть развернут несколько раз в одной функции, метка будет определена несколько раз в этой функции. Локальная метка устраняет эту проблему. Например:

#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)

Это также можно записать с использованием выражения оператора:

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

Локальные объявления меток также делают объявленные ими метки видимыми для вложенных функций, если таковые имеются. Подробнее см. Вложенные функции.

Далее: Метки как значения, Предыдущее: Выражения операторов, Наверх: Расширения C [Содержание][Индекс]

© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-8.5.0/gcc/Local-Labels.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API