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