Namespaces
Variants

goto statement

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
goto - return
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

Transfiere el control incondicionalmente.

Se utiliza cuando de otro modo es imposible transferir el control a la ubicación deseada utilizando otras sentencias.

Contenidos

Sintaxis

attr  (opcional) goto etiqueta ;

Explicación

La instrucción goto transfiere el control a la ubicación especificada por la etiqueta . La instrucción goto debe estar en la misma función que la etiqueta a la que se refiere, y puede aparecer antes o después de la etiqueta.

Si la transferencia de control sale del ámbito de cualquier variable automática (por ejemplo, saltando hacia atrás a un punto anterior a las declaraciones de dichas variables o saltando hacia adelante fuera de una sentencia compuesta donde las variables tienen ámbito), los destructores son llamados para todas las variables cuyo ámbito fue abandonado, en el orden opuesto al orden de su construcción.

La declaración goto no puede transferir el control hacia una declaración de control de flujo limitado , pero puede transferir el control fuera de una declaración de control de flujo limitado (se siguen las reglas mencionadas anteriormente respecto a las variables automáticas en alcance).

Si la transferencia de control entra en el ámbito de cualquier variable automática (por ejemplo, saltando hacia adelante sobre una declaración), el programa está mal formado (no puede compilarse), a menos que todas las variables cuyo ámbito se ingresa tengan los siguientes tipos:

  • tipos escalares declarados sin inicializadores
  • tipos de clase con constructores por defecto triviales y destructores triviales declarados sin inicializadores
  • versiones calificadas cv de uno de los anteriores
  • arrays de uno de los anteriores

(Nota: las mismas reglas se aplican a todas las formas de transferencia de control)

Notas

En el lenguaje de programación C, la sentencia goto tiene menos restricciones y puede entrar en el ámbito de cualquier variable excepto arreglos de longitud variable o punteros modificables variablemente.

Palabras clave

goto

Ejemplo

#include <iostream>
struct Object
{
    // destructor no trivial
    ~Object() { std::cout << 'd'; }
};
struct Trivial
{
    double d1;
    double d2;
}; // ctor y dtor triviales
int main()
{
    int a = 10;
    // bucle usando goto
label:
    Object obj;
    std::cout << a << ' ';
    a -= 2;
    if (a != 0)
        goto label;  // salta fuera del ámbito de obj, llama al destructor de obj
    std::cout << '\n';
    // goto puede usarse para salir eficientemente de bucles multinivel (anidados)
    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; // salta al ámbito de n y t
    [[maybe_unused]] int n; // sin inicializador
    [[maybe_unused]] Trivial t; // ctor/dtor trivial, sin inicializador
//  int x = 1;   // error: tiene inicializador
//  Object obj2; // error: destructor no trivial
label2:
    {
        Object obj3;
        goto label3; // salta hacia adelante, fuera del ámbito de obj3
    }
label3:
    std::cout << '\n';
}

Salida:

10 d8 d6 d4 d2
(0,0)
(0,1)
(0,2)
(1,0)
(1,1)
(1,2)
d
d

Véase también

Enlaces externos

El popular ensayo de Edsger W. Dijkstra, “Goto Considered Harmful” (originalmente, en "Letter to Communications of the ACM (CACM)", vol. 11 #3, marzo de 1968, pp. 147-148.), presenta un análisis de los muchos problemas sutiles que el uso descuidado de esta palabra clave puede introducir.