goto оператор
Безусловно передаёт управление.
Используется, когда передать управление в нужное место с помощью других операторов невозможно.
Синтаксис
attr (optional) goto label ; |
Пояснение
Оператор goto передаёт управление в место, указанное меткой. Оператор goto должен находиться в той же функции, что и метка label, на которую он ссылается; он может располагаться до или после метки.
Если передача управления выходит из области видимости каких-либо автоматических переменных (например, при переходе назад к месту перед объявлениями таких переменных или при переходе вперёд за пределы составного оператора, в котором определена их область видимости), вызываются деструкторы всех переменных, область видимости которых была покинута, в порядке, обратном порядку их создания.
Оператор goto не может передавать управление внутрь оператора с ограниченным потоком управления, но может передавать управление из такого оператора (при этом соблюдаются приведённые выше правила для автоматических переменных в области видимости).
Если при передаче управления выполнение попадает в область видимости каких-либо автоматических переменных (например, при переходе вперёд через оператор объявления), программа некорректна (не может быть скомпилирована), если только все переменные, в область видимости которых попадает выполнение, не имеют следующих типов:
- скалярные типы, объявленные без инициализаторов
- типы классов с тривиальными конструкторами по умолчанию и тривиальными деструкторами, объявленные без инициализаторов
- версии одного из перечисленных выше типов с квалификаторами cv
- массивы одного из перечисленных выше типов
(Примечание: те же правила применяются ко всем формам передачи управления.)
Примечания
В языке программирования C оператор goto имеет меньше ограничений и может входить в область видимости любой переменной, кроме массива переменной длины или указателя с модифицируемым типом.
Ключевые слова
Пример
#include <iostream>
struct Object
{
// non-trivial destructor
~Object() { std::cout << 'd'; }
};
struct Trivial
{
double d1;
double d2;
}; // trivial ctor and dtor
int main()
{
int a = 10;
// loop using goto
label:
Object obj;
std::cout << a << ' ';
a -= 2;
if (a != 0)
goto label; // jumps out of scope of obj, calls obj destructor
std::cout << '\n';
// goto can be used to efficiently leave a multi-level (nested) loops
for (int x = 0; x < 3; ++x)
for (int y = 0; y < 3; ++y)
{
std::cout << '(' << x << ',' << y << ") " << '\n';
if (x + y >= 3)
goto endloop;
}
endloop:
std::cout << '\n';
goto label2; // jumps into the scope of n and t
[[maybe_unused]] int n; // no initializer
[[maybe_unused]] Trivial t; // trivial ctor/dtor, no initializer
// int x = 1; // error: has initializer
// Object obj2; // error: non-trivial dtor
label2:
{
Object obj3;
goto label3; // jumps forward, out of scope of obj3
}
label3:
std::cout << '\n';
}
Вывод:
10 d8 d6 d4 d2 (0,0) (0,1) (0,2) (1,0) (1,1) (1,2) d d
См. также
Документация по C для goto |
Внешние ссылки
| Популярное эссе Эдсгера В. Дейкстры «О вреде оператора goto» (первоначально опубликованное в «Письме в журнал Communications of the ACM (CACM)», т. 11, № 3, март 1968 г., стр. 147–148) содержит обзор множества тонких проблем, которые может вызвать неосторожное использование этого ключевого слова. |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/language/goto