Оператор goto
Безусловно передаёт управление.
Используется, когда иначе невозможно передать управление в нужное место с помощью других операторов.
Содержание |
[править]Синтаксис
атрибуты (необязательно)goto метка; | |||||||||
[править]Объяснение
Оператор goto передаёт управление в место, указанное меткой. Оператор goto должен находиться в той же функции, что и метка, на которую он ссылается, он может стоять до или после метки.
Если передача управления выходит за пределы области видимости каких-либо автоматических переменных (например, при переходе назад к точке перед объявлениями таких переменных или при переходе вперёд из составного оператора, в котором переменные ограничены областью видимости), деструкторы вызываются для всех переменных, из области видимости которых осуществляется выход, в порядке обратном порядку их построения.
Оператор goto
не может передать управление в блок try или в предложение catch, но может передать управление из блока try или предложения catch (соблюдаются приведённые выше правила в отношении автоматических переменных в области видимости).
Если передача управления входит в область видимости каких-либо автоматических переменных (например, при переходе вперёд через оператор объявления), программа некорректна (не может быть скомпилирована), если только все переменные, область видимости которых является текущей, не имеют значения
(Примечание: ко всем формам передачи контроля применяются одни и те же правила)
[править]Ключевые слова
[править]Примечание
В языке программирования C оператор goto
имеет меньше ограничений и может входить в область видимости любой переменной, кроме массива переменной длины или указателя на изменяемую переменную.
[править]Пример
#include <iostream> struct Object {// нетривиальный деструктор ~Object(){std::cout<<'d';}}; struct Trivial {double d1;double d2;};// тривиальный конструктор и деструктор int main(){int a =10; // цикл с использованием goto label: Object obj;std::cout<< a <<' '; a -=2; if(a !=0){goto label;// выходит за область видимости obj, вызывает деструктор obj}std::cout<<'\n'; // goto можно использовать для эффективного выхода из многоуровневых (вложенных) циклов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;// переход в область видимости n и t[[maybe_unused]]int n;// нет инициализатора[[maybe_unused]] Trivial t;// тривиальный конструктор/деструктор, без инициализатора// int x = 1; // ошибка: есть инициализатор// Object obj2; // ошибка: нетривиальный деструктор label2:{ Object obj3;goto label3;// переход вперёд, за область видимости 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 Считается Вредным” (первоначально в "Письме к сообщениям ACM (CACM)", том 11 #3, март 1968, стр. 147-148.), представляет обзор многих тонких проблем, которые может создать неосторожное использование этого ключевого слова. |