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-6.5.0/gcc/Local-Labels.html