Namespaces
Variants

goto statement

From cppreference.net

Transfiere el control incondicionalmente a la ubicación deseada.

Se utiliza cuando es imposible transferir el control a la ubicación deseada utilizando construcciones convencionales.

Contenidos

Sintaxis

attr-spec-seq (opcional) goto label ;
label - etiqueta de destino label para la sentencia goto
attr-spec-seq - (C23) lista opcional de attributes , aplicada a la sentencia goto

Explicación

La sentencia goto provoca un salto incondicional (transferencia de control) a la sentencia precedida por la etiqueta nombrada (que debe aparecer en la misma función que la sentencia goto) , excepto cuando este salto entraría en el ámbito de un arreglo de longitud variable u otro tipo modificable variable . (desde C99)

Una etiqueta es un identificador seguido de dos puntos ( : ) y una sentencia (hasta C23) . Las etiquetas son los únicos identificadores que tienen alcance de función : pueden usarse (en una sentencia goto) en cualquier parte de la misma función en la que aparecen. Puede haber múltiples etiquetas antes de cualquier sentencia.

Se permite entrar en el ámbito de una variable no modificable de forma variable:

goto lab1; // OK: entrando en el ámbito de una variable regular
    int n = 5;
lab1:; // Nota: n no está inicializada, como si se declarara por int n;
//   goto lab2;   // Error: entrando en el ámbito de dos tipos VM
     double a[n]; // un VLA
     int (*p)[n]; // un puntero VM
lab2:

Si goto sale del ámbito de un VLA, este se desasigna (y puede reasignarse si su inicialización se ejecuta nuevamente):

{
   int n = 1;
label:;
   int a[n]; // reasignado 10 veces, cada una con un tamaño diferente
   if (n++ < 10) goto label; // saliendo del ámbito de un VM
}
(desde C99)

Palabras clave

goto

Notas

Dado que las declaraciones no son sentencias, una etiqueta antes de una declaración debe usar una sentencia nula (un punto y coma inmediatamente después de los dos puntos). Lo mismo se aplica a una etiqueta antes del final de un bloque.

(until C23)

C++ impone limitaciones adicionales sobre la goto statement, pero permite etiquetas antes de declaraciones (que son statements en C++).

Ejemplo

#include <stdio.h>
int main(void)
{
    // goto puede usarse para salir fácilmente de un bucle multinivel
    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:;
}

Salida:

(0;0)
(0;1)
(0;2)
(1;0)
(1;1)
(1;2)

Referencias

  • Estándar C17 (ISO/IEC 9899:2018):
  • 6.8.6.1 La sentencia goto (p: 110-111)
  • Estándar C11 (ISO/IEC 9899:2011):
  • 6.8.6.1 La sentencia goto (p: 152-153)
  • Estándar C99 (ISO/IEC 9899:1999):
  • 6.8.6.1 La sentencia goto (p: 137-138)
  • Estándar C89/C90 (ISO/IEC 9899:1990):
  • 3.6.6.1 La sentencia goto

Véase también

Documentación de C++ para goto statement