Пространства имён
Варианты
Действия

Инструкция goto

Материал из cppreference.com

Передаёт управление безусловно в желаемую точку.

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

Синтаксис

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

Объяснение

Инструкция goto вызывает безусловный переход (передачу управления) на инструкцию, помеченную меткой (которая обязана присутствовать в той же функции, что и инструкция goto), за исключением случая перехода в область видимости массива переменной длины или иного переменно-модифицируемого типа. (начиная с C99)

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

Переход в область видимости не переменно-модифицируемого типа разрешён:

goto lab1; // нормально: переходим в область видимости обычной переменной
    int n = 5;
lab1:; // Обратите внимание, n неинициализирована, будто бы объявлена как int n;

//   goto lab2;   // Ошибка: переходим в область видимости двух ПМ типов
     double a[n]; // массив переменной длины
     int (*p)[n]; // указатель на массив переменной длины
lab2:

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

{
   int n = 1;
label:;
   int a[n]; // перевыделяется 10 раз, каждый раз с разным размером
   if (n++ < 10) goto label; // покидаем область видимости ПМ
}
(начиная с 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