Namespaces
Variants

goto statement

From cppreference.net

Безусловно передает управление в указанное место.

Используется, когда иным способом невозможно передать управление в нужное место с помощью стандартных конструкций.

Содержание

Синтаксис

attr-spec-seq (необязательно) goto label ;
label - целевая метка label для оператора goto
attr-spec-seq - (C23) опциональный список attributes , применяемых к оператору goto

Объяснение

Оператор goto вызывает безусловный переход (передачу управления) к оператору, перед которым стоит указанная метка (которая должна находиться в той же функции, что и оператор goto) , за исключением случаев, когда этот переход приводит к входу в область видимости variable-length array или другого variably-modified type . (since C99)

Метка label - это идентификатор, за которым следует двоеточие ( : ) и оператор (до C23) . Метки являются единственными идентификаторами, имеющими область видимости функции : они могут использоваться (в операторе goto) в любом месте той же функции, в которой они объявлены. Перед любым оператором может быть несколько меток.

Вход в область видимости невариационно модифицированной переменной разрешен:

goto lab1; // OK: переход в область видимости обычной переменной
    int n = 5;
lab1:; // Примечание: n не инициализирована, как если бы объявлена через int n;
//   goto lab2;   // Ошибка: переход в область видимости двух VM типов
     double a[n]; // VLA
     int (*p)[n]; // VM указатель
lab2:

Если goto покидает область видимости VLA, она освобождается (и может быть перераспределена при повторном выполнении её инициализации):

{
   int n = 1;
label:;
   int a[n]; // перераспределяется 10 раз, каждый раз с разным размером
   if (n++ < 10) goto label; // покидание области видимости VM
}
(начиная с C99)

Ключевые слова

goto

Примечания

Поскольку объявления не являются инструкциями, метка перед объявлением должна использовать пустую инструкцию (точку с запятой сразу после двоеточия). То же самое относится к метке перед концом блока.

(до C23)

C++ накладывает дополнительные ограничения на оператор goto , но позволяет использовать метки перед объявлениями (которые в C++ являются операторами).

Пример

#include <stdio.h>
int main(void)
{
    // goto можно использовать для простого выхода из многоуровневого цикла
    for (int x = 0; x < 3; x++) {
        for (int y = 0; y < 3; y++) {
            printf("(%d;%d)\n",x,y);
            if (x + y >= 3) goto endloop;
        }
    }
endloop:;
}

Вывод:

(0;0)
(0;1)
(0;2)
(1;0)
(1;1)
(1;2)

Ссылки

  • Стандарт C17 (ISO/IEC 9899:2018):
  • 6.8.6.1 Оператор goto (стр: 110-111)
  • Стандарт C11 (ISO/IEC 9899:2011):
  • 6.8.6.1 Оператор goto (стр: 152-153)
  • Стандарт C99 (ISO/IEC 9899:1999):
  • 6.8.6.1 Оператор goto (стр: 137-138)
  • Стандарт C89/C90 (ISO/IEC 9899:1990):
  • 3.6.6.1 Оператор goto

Смотрите также

Документация C++ для goto оператора