Spec-Zone.ru › C++

Оператор goto

Безусловный переход.

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

Синтаксис

attr (необязательно) goto метка ;

Объяснение

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

Если передача управления выходит за область действия каких-либо автоматических переменных (например, при переходе назад к точке до объявлений таких переменных или при переходе вперёд за пределы составного оператора, где определены переменные), деструкторы вызываются для всех переменных, область действия которых завершилась, в порядке, обратном порядку их создания.

Оператор goto не может передать управление внутрь блока try или в раздел catch, но может передать управление наружу блока try или раздела catch (при этом соблюдаются вышеуказанные правила относительно автоматических переменных в области действия).

Если передача управления попадает в область действия каких-либо автоматических переменных (например, при переходе вперёд через оператор объявления), программа является некорректной (не может быть скомпилирована), если все переменные, область действия которых входит, имеют

1) скалярные типы, объявленные без инициализаторов
2) классы с тривиальными конструкторами по умолчанию и тривиальными деструкторами, объявленные без инициализаторов
3) квалифицированные версии одного из вышеперечисленных
4) массивы одного из вышеперечисленных

(Примечание: те же правила применяются ко всем формам передачи управления)

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

goto

Примечания

В языке программирования 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 Considered Harmful” (первоначально, в «Письме в 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/w/cpp/language/goto

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API