Spec-Zone.ru › GCC 10

Следующая: Метки как значения, Предыдущая: Операторные выражения и объявления в выражениях, Вверх: Расширения языка семейства C [Оглавление][Индекс]

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

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

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

__label__ label;

или

__label__ label1, label2, /* … */;

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

Объявление метки определяет имя метки name, но не саму метку. Вы должны сделать это обычным способом, с 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-10.5.0/gcc/Local-Labels.html

Spec-Zone.ru

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