Ir a

Declaración de control unidireccional en programación informática
Tecla " GOTO " en la computadora doméstica ZX Spectrum de 1982 , implementada con BASIC nativo (entrada de comando con una sola tecla).

Goto es una declaración que se encuentra en muchos lenguajes de programación informática . Realiza una transferencia unidireccional de control a otra línea de código; en contraste, una llamada a una función normalmente devuelve el control. Las ubicaciones a las que se salta normalmente se identifican mediante etiquetas , aunque algunos lenguajes utilizan números de línea . A nivel de código de máquina , una gotoes una forma de declaración de salto o ramificación , en algunos casos combinada con un ajuste de pila. Muchos lenguajes admiten la gotodeclaración y muchos no (consulte § compatibilidad de lenguajes).

El teorema del programa estructurado demostró que la gotoafirmación no es necesaria para escribir programas que puedan expresarse como diagramas de flujo ; alguna combinación de las tres construcciones de programación de secuencia, selección/elección y repetición/iteración es suficiente para cualquier cálculo que pueda ser realizado por una máquina de Turing , con la salvedad de que puede ser necesario introducir duplicación de código y variables adicionales. [1]

El uso de goto era común en el pasado, pero desde la llegada de la programación estructurada en los años 1960 y 1970, su uso ha disminuido significativamente. Sigue utilizándose en ciertos patrones de uso comunes, pero generalmente se utilizan alternativas si están disponibles. En el pasado, hubo un debate considerable en el ámbito académico y en la industria sobre los méritos del uso de las instrucciones goto. La principal crítica es que el código que utiliza instrucciones goto es más difícil de entender que las construcciones alternativas. Los debates sobre sus usos (más limitados) continúan en los círculos académicos y de la industria del software.

Uso

goto label

La gotodeclaración a menudo se combina con la declaración if para provocar una transferencia condicional de control.

IF condition THEN goto label

Los lenguajes de programación imponen distintas restricciones con respecto al destino de una gotoinstrucción. Por ejemplo, el lenguaje de programación C no permite un salto a una etiqueta contenida dentro de otra función, [2] sin embargo, los saltos dentro de una sola cadena de llamadas son posibles utilizando las funciones setjmp/longjmp .

Crítica

En la reunión previa a ALGOL celebrada en 1959, Heinz Zemanek puso en duda explícitamente la necesidad de las sentencias GOTO; en ese momento nadie [ cita requerida ] prestó atención a su observación, incluido Edsger W. Dijkstra , quien más tarde se convirtió en el oponente icónico de GOTO. [3] Las décadas de 1970 y 1980 vieron un declive en el uso de sentencias GOTO a favor del paradigma de programación estructurada , con GOTO criticado por conducir a un código espagueti inmantenible . Algunos estándares de codificación de estilo de programación , por ejemplo los Estándares de codificación GNU Pascal, recomiendan no usar sentencias GOTO. [4] La prueba de Böhm-Jacopini (1966) no resolvió la cuestión de si adoptar la programación estructurada para el desarrollo de software, en parte porque la construcción tenía más probabilidades de oscurecer un programa que de mejorarlo porque su aplicación requiere la introducción de variables locales adicionales. [5] Sin embargo, desencadenó un importante debate entre científicos informáticos, educadores, diseñadores de lenguajes y programadores de aplicaciones que vieron un cambio lento pero constante en el uso antes omnipresente de GOTO. Probablemente la crítica más famosa de GOTO es una carta de 1968 de Edsger Dijkstra llamada " Declaración Go-to considerada dañina ". [3] En esa carta, Dijkstra argumentó que las declaraciones GOTO sin restricciones deberían abolirse de los lenguajes de alto nivel porque complicaban la tarea de analizar y verificar la corrección de los programas (en particular aquellos que involucraban bucles). [6] La carta en sí desencadenó un debate, incluida una carta ""GOTO considerado dañino" considerado dañino" [7] enviada a Comunicaciones de la ACM (CACM) en marzo de 1987, así como otras respuestas de otras personas, incluida la de Dijkstra en Sobre una correspondencia algo decepcionante . [8]

Un punto de vista alternativo se presenta en Structured Programming with go to Statements de Donald Knuth , que analiza muchas tareas de programación comunes y descubre que en algunas de ellas GOTO es la construcción de lenguaje óptima para usar. [9] En The C Programming Language , Brian Kernighan y Dennis Ritchie advierten que es "infinitamente abusable", pero también sugieren que podría usarse para manejadores de errores de fin de función y para cortes de múltiples niveles de bucles. [10] Estos dos patrones se pueden encontrar en numerosos libros posteriores sobre C de otros autores; [11] [12] [13] [14] un libro de texto introductorio de 2007 señala que el patrón de manejo de errores es una forma de evitar la "falta de manejo de excepciones incorporado dentro del lenguaje C". [11] Otros programadores, incluido el diseñador y codificador del kernel de Linux Linus Torvalds o el ingeniero de software y autor de libros Steve McConnell , también se oponen al punto de vista de Dijkstra, afirmando que los GOTO pueden ser una característica útil del lenguaje, mejorando la velocidad del programa, el tamaño y la claridad del código, pero solo cuando se usan de manera sensata por un programador comparativamente sensato. [15] [16] Según el profesor de informática John Regehr , en 2013, había alrededor de 100.000 instancias de goto en el código del kernel de Linux. [17]goto

Otros académicos adoptaron un punto de vista más extremo y argumentaron que incluso instrucciones como breaky returndesde el medio de los bucles son una mala práctica, ya que no son necesarias en el resultado de Böhm-Jacopini, y por lo tanto defendieron que los bucles deberían tener un único punto de salida. [18] Por ejemplo, Bertrand Meyer escribió en su libro de texto de 2009 que instrucciones como breaky continue"son simplemente las viejas gotocon piel de oveja". [19] Sin embargo, una forma ligeramente modificada del resultado de Böhm-Jacopini permite evitar variables adicionales en la programación estructurada, siempre que se permitan cortes de varios niveles de los bucles. [20] Debido a que algunos lenguajes como C no permiten cortes de varios niveles a través de su breakpalabra clave, algunos libros de texto recomiendan al programador que utilice gotoen tales circunstancias. [14] El estándar MISRA C 2004 prohíbe goto, continue, así como múltiples declaraciones returny break. [21] La edición 2012 del estándar MISRA C degradó la prohibición gotode "requerida" a "consultiva"; la edición 2012 tiene una regla adicional obligatoria que prohíbe solo los saltos hacia atrás, pero no hacia adelante con goto. [22] [23]

FORTRAN introdujo construcciones de programación estructurada en 1978, y en revisiones sucesivas las reglas semánticas relativamente laxas que regulaban el uso permitido de goto se hicieron más estrictas; el "rango extendido" en el que un programador podía usar un GOTO para salir y volver a entrar en un bucle DO que aún se estaba ejecutando se eliminó del lenguaje en 1978, [24] y para 1995 se habían eliminado varias formas de Fortran GOTO, incluyendo el GOTO calculado y el GOTO asignado. [25] Algunos lenguajes de programación modernos ampliamente utilizados como Java y Python carecen de la declaración GOTO (ver soporte de lenguaje), aunque la mayoría proporciona algún medio para salir de una selección, o bien para salir o pasar al siguiente paso de una iteración. El punto de vista de que alterar el flujo de control en el código es indeseable se puede ver en el diseño de algunos lenguajes de programación, por ejemplo Ada [26] enfatiza visualmente las definiciones de etiquetas usando corchetes angulares .

La entrada 17.10 en la lista de preguntas frecuentes de comp.lang.c [27] aborda el problema del uso de GOTO directamente, indicando

El estilo de programación, al igual que el estilo de escritura, es algo así como un arte y no se puede codificar mediante reglas inflexibles, aunque las discusiones sobre el estilo a menudo parecen centrarse exclusivamente en torno a dichas reglas. En el caso de la sentencia goto, se ha observado durante mucho tiempo que el uso sin restricciones de goto conduce rápidamente a un código espagueti inmantenible. Sin embargo, una prohibición simple e irreflexiva de la sentencia goto no conduce necesariamente de inmediato a una programación hermosa: un programador no estructurado es igualmente capaz de construir una maraña bizantina sin utilizar ninguna sentencia goto (quizás sustituyendo bucles anidados de forma extraña y variables de control booleanas, en su lugar). Muchos programadores adoptan una postura moderada: las sentencias goto suelen evitarse, pero son aceptables en unas pocas situaciones bien restringidas, si es necesario: como sentencias break de varios niveles, para fusionar acciones comunes dentro de una sentencia switch o para centralizar tareas de limpieza en una función con varios retornos de error. (...) Evitar ciegamente ciertas construcciones o seguir reglas sin comprenderlas puede conducir a tantos problemas como los que se supone que las reglas deben evitar. Además, muchas opiniones sobre el estilo de programación son sólo eso: opiniones. Pueden estar fuertemente argumentadas y sentidas, pueden estar respaldadas por evidencias y argumentos aparentemente sólidos, pero las opiniones opuestas pueden estar igualmente fuertemente sentidas, apoyadas y argumentadas. Por lo general, es inútil involucrarse en "guerras de estilos", porque en ciertas cuestiones, los oponentes nunca parecen estar de acuerdo, o acordar estar en desacuerdo, o dejar de discutir.

Patrones de uso comunes

Si bien el uso general de goto ha ido disminuyendo, aún existen situaciones en algunos lenguajes en las que un goto proporciona la forma más corta y directa de expresar la lógica de un programa (si bien es posible expresar la misma lógica sin gotos, el código equivalente será más largo y, a menudo, más difícil de entender). En otros lenguajes, existen alternativas estructuradas, en particular excepciones y llamadas finales.

Las situaciones en las que goto suele ser útil incluyen:

  • Para hacer el código más legible y fácil de seguir [15] [28]
  • Para hacer programas más pequeños y eliminar la duplicación de código [15] [28]
  • Implementar una máquina de estados finitos , utilizando una tabla de transición de estados y goto para cambiar entre estados (en ausencia de eliminación de llamadas de cola ), particularmente en código C generado automáticamente. [29] Por ejemplo, goto en el analizador LR canónico .
  • Implementación de saltos y continuaciones de varios niveles si no se admiten directamente en el lenguaje; este es un modismo común en C. [14] Aunque Java reserva la palabra clave goto, en realidad no la implementa. En su lugar, Java implementa sentencias etiquetadas como saltos y continuaciones. [30] Según la documentación de Java, el uso de gotos para saltos de varios niveles fue el uso más común (90%) de gotos en C. [31] Java no fue el primer lenguaje en adoptar este enfoque (prohibiendo goto, pero proporcionando saltos de varios niveles); el lenguaje de programación BLISS (más precisamente, la versión BLISS-11 del mismo) lo precedió en este sentido. [32]
  • Sustitutos de las sentencias break o continue (retry) de un solo nivel cuando la posible introducción de bucles adicionales podría afectar incorrectamente el flujo de control. Esta práctica se ha observado en el código NetBSD . [33]
  • Manejo de errores (en ausencia de excepciones), particularmente código de limpieza como la desasignación de recursos. [11] [14] [33] [29] [34] C++ ofrece una alternativa a la declaración goto para este caso de uso, que es: La adquisición de recursos es inicialización (RAII) mediante el uso de destructores o el uso de excepciones try y catch utilizadas en el manejo de excepciones . [35] setjmp y longjmp son otra alternativa y tienen la ventaja de poder desenrollar parte de la pila de llamadas .
  • Introduciendo la pila, por ejemplo, Algol, PL/I.
  • Lenguajes de programación especializados que funcionan de manera lineal, como un sistema de diálogo para videojuegos. [36]

Estos usos son relativamente comunes en C, pero mucho menos comunes en C++ u otros lenguajes con características de nivel superior. [34] Sin embargo, lanzar y capturar una excepción dentro de una función puede ser extraordinariamente ineficiente en algunos lenguajes; un buen ejemplo es Objective-C , donde un goto es una alternativa mucho más rápida. [37]

Otro uso de las sentencias goto es modificar código heredado mal factorizado , donde evitar un goto requeriría una refactorización extensa o duplicación de código . Por ejemplo, dada una función grande donde solo cierto código es de interés, una sentencia goto permite saltar hacia o desde solo el código relevante, sin modificar de otra manera la función. Este uso se considera un error de código [38] , pero se usa ocasionalmente.

Alternativas

Programación estructurada

La noción moderna de subrutina fue inventada por David Wheeler cuando programó el EDSAC . Para implementar una llamada y un retorno en una máquina sin una instrucción de llamada de subrutina, utilizó un patrón especial de código automodificable, conocido como salto de Wheeler . [39] Esto dio como resultado la capacidad de estructurar programas utilizando ejecuciones bien anidadas de rutinas extraídas de una biblioteca. Esto no habría sido posible utilizando solo goto, ya que el código de destino, al ser extraído de la biblioteca, no sabría a dónde volver a saltar.

Más tarde, se diseñaron lenguajes de alto nivel como Pascal en torno al soporte de la programación estructurada , que se generalizó desde subrutinas (también conocidas como procedimientos o funciones) hacia otras estructuras de control como:

Estos nuevos mecanismos de lenguaje reemplazaron flujos equivalentes que antes se habrían escrito utilizando gotos y ifs. La ramificación multidireccional reemplaza el "goto calculado" en el que la instrucción a la que se debe saltar se determina dinámicamente (condicionalmente).

Bajo ciertas condiciones, es posible eliminar las declaraciones goto locales de programas heredados reemplazándolas con declaraciones de salida de bucle multinivel. [40]

Excepciones

En la práctica, una estricta adherencia a la plantilla básica de tres estructuras de la programación estructurada produce un código altamente anidado, debido a la incapacidad de salir prematuramente de una unidad estructurada, y una explosión combinatoria con datos de estado del programa bastante complejos para manejar todas las condiciones posibles.

En general, se han adoptado dos soluciones: una forma de salir de una unidad estructurada de forma prematura y, de forma más general, excepciones : en ambos casos, estas suben por la estructura y devuelven el control a los bloques o funciones que las contienen, pero no saltan a ubicaciones de código arbitrarias. Estas son análogas al uso de una sentencia return en una posición no terminal: no estrictamente estructurada, debido a la salida temprana, sino una relajación leve de las restricciones de la programación estructurada. En C, breaky continuepermiten terminar un bucle o continuar con la siguiente iteración , sin requerir una sentencia whileor adicional if. En algunos lenguajes, también son posibles los cortes de varios niveles. Para manejar situaciones excepcionales, se agregaron construcciones especializadas de manejo de excepciones , como try/ catch/ finallyen Java.

Los mecanismos de manejo de excepciones throw-catch también pueden ser fácilmente abusados ​​para crear estructuras de control no transparentes, al igual que se puede abusar de goto. [41]

Llamadas de cola

En un artículo presentado en la conferencia ACM en Seattle en 1977, Guy L. Steele resumió el debate sobre GOTO y la programación estructurada, y observó que las llamadas a procedimientos en la posición de cola de un procedimiento pueden tratarse de manera más óptima como una transferencia directa de control al procedimiento llamado, eliminando típicamente operaciones de manipulación de pila innecesarias. [42] Dado que estas "llamadas de cola" son muy comunes en Lisp , un lenguaje donde las llamadas a procedimientos son ubicuas, esta forma de optimización reduce considerablemente el costo de una llamada a procedimiento en comparación con el GOTO utilizado en otros lenguajes. Steele argumentó que las llamadas a procedimientos mal implementadas habían llevado a una percepción artificial de que el GOTO era barato en comparación con la llamada a procedimiento. Steele argumentó además que "en general, las llamadas a procedimientos pueden considerarse de manera útil como instrucciones GOTO que también pasan parámetros y pueden codificarse uniformemente como instrucciones JUMP de código de máquina ", con las instrucciones de manipulación de pila de código de máquina "consideradas una optimización (¡en lugar de al revés!)". [42] Steele citó evidencia de que los algoritmos numéricos bien optimizados en Lisp podían ejecutarse más rápido que el código producido por los compiladores Fortran comerciales disponibles en ese momento porque el costo de una llamada a un procedimiento en Lisp era mucho menor. En Scheme , un dialecto de Lisp desarrollado por Steele con Gerald Jay Sussman , la optimización de la llamada de cola es obligatoria. [43]

Aunque el artículo de Steele no introdujo muchas novedades en la ciencia informática, al menos tal como se practicaba en el MIT, sacó a la luz el alcance de la optimización de las llamadas a procedimientos, lo que convirtió las cualidades de promoción de la modularidad de los procedimientos en una alternativa más creíble a los hábitos de codificación entonces comunes de los grandes procedimientos monolíticos con estructuras de control interno complejas y datos de estado extensos. En particular, las optimizaciones de llamadas de cola discutidas por Steele convirtieron el procedimiento en una forma creíble de implementar la iteración a través de la recursión de cola única (recursión de cola que llama a la misma función). Además, la optimización de llamadas de cola permite la recursión mutua de profundidad ilimitada, suponiendo llamadas de cola; esto permite la transferencia de control, como en las máquinas de estados finitos , que de lo contrario generalmente se logra con instrucciones goto.

Corrutinas

Las corrutinas son una relajación más radical de la programación estructurada, permitiendo no solo múltiples puntos de salida (como retornos en posición no de cola), sino también múltiples puntos de entrada, similares a las declaraciones goto. Las corrutinas son más restringidas que goto, ya que solo pueden reanudar una corrutina que se esté ejecutando actualmente en puntos específicos (continuando después de un yield) en lugar de saltar a un punto arbitrario en el código. Una forma limitada de corrutinas son los generadores , que son suficientes para algunos propósitos. Aún más limitados son los cierres : subrutinas que mantienen el estado (a través de variables estáticas ), pero no la posición de ejecución. Una combinación de variables de estado y control estructurado, en particular una declaración switch general, puede permitir que una subrutina reanude la ejecución en un punto arbitrario en llamadas posteriores, y es una alternativa estructurada a las declaraciones goto en ausencia de corrutinas; este es un modismo común en C, por ejemplo.

Continuaciones

Una continuación es similar a un GOTO en el sentido de que transfiere el control desde un punto arbitrario en el programa a un punto marcado previamente. Una continuación es más flexible que GOTO en aquellos lenguajes que la admiten, porque puede transferir el control fuera de la función actual, algo que un GOTO no puede hacer en la mayoría de los lenguajes de programación estructurada. En aquellas implementaciones de lenguaje que mantienen marcos de pila para el almacenamiento de variables locales y argumentos de funciones, ejecutar una continuación implica ajustar la pila de llamadas del programa además de un salto. La función longjmp del lenguaje de programación C es un ejemplo de una continuación de escape que se puede utilizar para escapar del contexto actual a uno circundante. El operador GO de Common Lisp también tiene esta propiedad de desenrollado de pila, a pesar de que la construcción tiene un alcance léxico , ya que la etiqueta a la que se saltará puede referenciarse desde un cierre .

En Scheme , las continuaciones pueden incluso mover el control de un contexto externo a uno interno si se desea. Este control casi ilimitado sobre qué código se ejecuta a continuación hace que las estructuras de control complejas, como las corrutinas y la multitarea cooperativa, sean relativamente fáciles de escribir. [43]

Paso de mensajes

En los paradigmas no procedimentales, goto es menos relevante o completamente ausente. Una de las principales alternativas es el paso de mensajes , que es de particular importancia en computación concurrente , comunicación entre procesos y programación orientada a objetos . En estos casos, los componentes individuales no tienen una transferencia arbitraria de control, sino que el control general puede programarse de formas complejas, como por ejemplo a través de la preempción . Los influyentes lenguajes Simula y Smalltalk fueron de los primeros en introducir los conceptos de mensajes y objetos. Al encapsular los datos de estado, la programación orientada a objetos redujo la complejidad del software a las interacciones (mensajes) entre objetos.

Variaciones

Hay varias construcciones de lenguaje diferentes bajo la clase de declaraciones goto .

GOTO calculadoyGOTO asignado

En Fortran , un salto calculadoGOTO pasa a una de varias etiquetas en una lista, en función del valor de una expresión. Un ejemplo es goto (20,30,40) i. [44] La construcción equivalente en C es la sentencia switch y en Fortran más reciente la SELECT CASEconstrucción a es la alternativa sintáctica recomendada. [45] BASIC tenía una 'On GoTo'sentencia que lograba el mismo objetivo, pero en Visual Basic esta construcción ya no se admite. [46]

En versiones anteriores a Fortran 95, Fortran también tenía una variante goto asignada que transfiere el control a una etiqueta de declaración (número de línea) que se almacena en (asignada a) una variable entera. Saltar a una variable entera que no había sido ASIGNADA era, lamentablemente, posible, y era una fuente importante de errores relacionados con gotos asignados. [47] La assign​​declaración de Fortran solo permite que se asigne un número de línea constante (existente) a la variable entera. Sin embargo, algunos compiladores permitían tratar accidentalmente esta variable como un entero a partir de entonces, por ejemplo, incrementarla, lo que resultaba en un comportamiento no especificado en gotoese momento. El siguiente código demuestra el comportamiento de goto icuando la línea i no está especificada:

 asignar 200 a i i = i + 1 ir a i ! comportamiento no especificado 200 escribir ( * , * ) "este es un número de línea válido"          

Varios compiladores de C implementan dos extensiones no estándar de C/C++ relacionadas con gotos introducidos originalmente por gcc . [48] La extensión GNU permite que la dirección de una etiqueta dentro de la función actual se obtenga como un operador de valor de etiquetavoid* de prefijo unario . La instrucción goto también se extiende para permitir saltar a una expresión arbitraria . Esta extensión de C se conoce como goto calculado en la documentación de los compiladores de C que la admiten; su semántica es un superconjunto del goto asignado de Fortran, porque permite expresiones de puntero arbitrarias como el objetivo del goto, mientras que el goto asignado de Fortran no permite expresiones arbitrarias como objetivo de salto. [49] Al igual que con el goto estándar en C, la extensión GNU C permite que el objetivo del goto calculado resida solo en la función actual. Intentar saltar fuera de la función actual da como resultado un comportamiento no especificado. [49] &&void*

Algunas variantes de BASIC también admiten un GOTO calculado en el sentido utilizado en GNU C, es decir, en el que el objetivo puede ser cualquier número de línea, no sólo uno de una lista. Por ejemplo, en MTS BASIC se podría escribir GOTO i*1000para saltar a la línea numerada 1000 veces el valor de una variable i (que podría representar una opción de menú seleccionada, por ejemplo). [50]

Las variables de etiqueta PL/I logran el efecto de GOTOs calculadas o asignadas.

ALTERAR

Hasta el estándar ANSI COBOL de 1985 , existía la declaración ALTER, que podía utilizarse para cambiar el destino de un GO TO existente, que tenía que estar en un párrafo por sí solo. [51] La característica, que permitía el polimorfismo , fue frecuentemente condenada y rara vez utilizada. [52]

GOTO de Perl

En Perl , existe una variante de la gotoinstrucción que no es una instrucción GOTO tradicional en absoluto. Toma un nombre de función y transfiere el control sustituyendo efectivamente una llamada de función por otra (una llamada de cola ): la nueva función no regresará a la instrucción GOTO, sino al lugar desde el que se llamó a la función original. [53]

GOTO emulado

Existen varios lenguajes de programación que no admiten GOTO de forma predeterminada. Si se utiliza la emulación GOTO, aún es posible utilizar GOTO en estos lenguajes de programación, aunque con algunas restricciones. Se puede emular GOTO en Java, [54] JavaScript, [55] y Python. [56] [57]

Variables de etiqueta PL/I

PL/I tiene el tipo de datos LABEL , que se puede utilizar para implementar tanto el "goto asignado" como el "goto calculado". PL/I permite ramificaciones fuera del bloque actual. Un procedimiento que llama puede pasar una etiqueta como argumento a un procedimiento llamado que luego puede salir con una ramificación. El valor de una variable de etiqueta incluye la dirección de un marco de pila, y un goto fuera del bloque hace que la pila salga de la pila.

/* Esto implementa el equivalente de */ /* el goto asignado */ declarar donde está la etiqueta; donde = en algún lugar; ir a donde; ... en algún lugar: /* declaración */ ; ...
/* Esto implementa el equivalente de */ /* el goto calculado */ declarar dónde (5) etiqueta; declarar inx fijo; donde(1) = abc; donde (2) = xyz; ... ir a donde(inx); ... abc: /* declaración */ ; ... xyz: /* declaración */ ; ...

Una forma más sencilla de obtener un resultado equivalente es utilizar una matriz de constantes de etiqueta que ni siquiera necesita una declaración explícita de una variable de tipo LABEL :

/* Esto implementa el equivalente de */ /* el goto calculado */ declarar inx fijo; ... ir a donde(inx); ... donde(1): /* declaración */ ; ... donde(2): /* declaración */ ; ...

Ir a MS/DOS

En un archivo por lotes de DOS , Goto dirige la ejecución a una etiqueta que comienza con dos puntos. El destino de Goto puede ser una variable.

@ echo off ESTABLECER  D8str = %date% ESTABLECER  D8dow = %D8str:~0,3%PARA  %% D en  ( lunes mié vie )  hacer  si  " %% D"  ==  " %D8dow% "  goto  SHOP%%D echo Hoy, %D8dow% , no es un día de compras. goto  end: SHOPMon echo compra pizza para el almuerzo - El lunes es el día de la pizza. ir  al final: SHOPWed echo comprar Calzone para llevar a casa - hoy es miércoles. ir  al final: SHOPFri echo comprar Seltzer en caso de que alguien quiera una bebida sin calorías. : fin

Soporte de idiomas

Muchos lenguajes soportan la gotodeclaración, y muchos no. En Java , gotoes una palabra reservada , pero no se puede usar, aunque .classlos archivos compilados generan GOTO y LABEL. [58] Python no tiene soporte para goto, aunque hay varios módulos de broma que lo proporcionan. [56] [57] No hay una declaración goto en Seed7 y los gotos ocultos como las declaraciones break y continue también se omiten. [59] En PHP no hubo soporte nativo para gotohasta la versión 5.3 (había bibliotecas disponibles para emular su funcionalidad). [60]

Tanto C# como Visual Basic .NET admiten goto. [61] [62] Sin embargo, no permite saltar a una etiqueta fuera del ámbito actual y respeta la eliminación de objetos y las construcciones finally, lo que lo hace significativamente menos poderoso y peligroso que la gotopalabra clave en otros lenguajes de programación. También hace que las etiquetas de las declaraciones case y default , cuyo ámbito es la declaración switch que las encierra ; goto case o goto default se usa a menudo como un reemplazo explícito para el fallthrough implícito, que C# no permite.

El lenguaje de programación PL/I tiene una declaración GOTO que desenrolla la pila para una transferencia fuera del bloque y no permite una transferencia a un bloque desde fuera del mismo.

Otros lenguajes pueden tener sus propias palabras clave para los fallthroughs explícitos, que pueden considerarse una versión gotorestringida a este propósito específico. Por ejemplo, Go usa la fallthroughpalabra clave y no permite fallthroughs implícitos en absoluto, [63] mientras que Perl 5 usa nextfallthroughs explícitos de manera predeterminada, pero también permite configurar fallthroughs implícitos como comportamiento predeterminado para un módulo.

La mayoría de los lenguajes que tienen instrucciones goto las llaman así, pero en los primeros tiempos de la informática se utilizaban otros nombres. Por ejemplo, en MAD se utilizaba la instrucción TRANSFER TO. [64] APL utiliza una flecha que apunta hacia la derecha para goto.

C tiene goto, y se usa comúnmente en varios modismos, como se mencionó anteriormente.

Los lenguajes de programación funcional como Scheme generalmente no tienen goto, en su lugar utilizan continuaciones.

Véase también

Notas

  1. ^ Watt y Findlay 2004.
  2. ^ Kernighan y Ritchie 1988, pág. 224, A9.6 Declaraciones de salto.
  3. ^ por Dijkstra 1968.
  4. ^ Equipo de desarrollo de GNU Pascal 2005, 5.1 Varios consejos de programación en Pascal.
  5. ^ Louden y Lambert 2012.
  6. ^ "El uso desenfrenado de la instrucción goto tiene como consecuencia inmediata que se hace terriblemente difícil encontrar un conjunto significativo de coordenadas con las que describir el progreso del proceso... La instrucción 'go to' tal como está es simplemente demasiado primitiva, es una invitación demasiado grande a arruinar el propio programa".
  7. ^ Rubín 1987.
  8. ^ Dijkstra, Edsger W. Sobre una correspondencia algo decepcionante (EWD-1009) (PDF) . Archivo EW Dijkstra. Centro de Historia Estadounidense, Universidad de Texas en Austin .(transcripción) (mayo de 1987)
  9. ^ Knuth 1974.
  10. ^ Kernighan y Ritchie 1988, págs. 65-66, 3.8 Ir a y etiquetas.
  11. ^ abc Vine 2007, pág. 262.
  12. ^ Geisler 2011.
  13. ^ Plata 2013.
  14. ^ abcd Sahni y Cmelik 1995.
  15. ^ Andrews 2003.
  16. ^ McConnell 2004.
  17. ^ Regla 2013.
  18. ^ Roberts 1995.
  19. ^ Meyer 2009.
  20. ^ Kozen y Tseng 2008.
  21. ^ Preguntas de Stack Overflow 2012.
  22. ^ Pitchford y Tapp 2013.
  23. ^ Williams 2013.
  24. ^ ANSI X3.9-1978. Estándar nacional estadounidense: lenguaje de programación FORTRAN. Instituto Nacional Estadounidense de Estándares. También conocido como ISO 1539-1980, informalmente conocido como FORTRAN 77
  25. ^ ISO/IEC 1539-1:1997. Tecnología de la información – Lenguajes de programación – Fortran – Parte 1: Lenguaje base. Conocido informalmente como Fortran 95. Esta norma consta de otras dos partes. La Parte 1 ha sido adoptada formalmente por ANSI.
  26. ^ Barnes 2006.
  27. ^ Cumbre 1995.
  28. ^por Torvalds 2016.
  29. ^Por Cozens 2004.
  30. ^ Tutorial de Java 2012.
  31. ^ Gosling y McGilton 1996.
  32. ^ Brender 2002, págs. 960–965.
  33. ^ por Spinellis 2003.
  34. ^Por Allain 2019.
  35. ^ Stroustrup 2012.
  36. ^ Hoad, Nathan (28 de julio de 2022). «nathanhoad/godot_dialogue_manager». GitHub . Consultado el 3 de febrero de 2023 .
  37. ^ Chisnall 2012.
  38. ^ Contieri 2021.
  39. ^ Wilkes, Wheeler y Gill 1951.
  40. ^ Ramshaw 1988.
  41. ^ Siedersleben 2006.
  42. ^Por Steele 1977.
  43. ^ por Kelsey, Clinger y Rees 1998.
  44. ^ , lo que significa que el programa salta a la etiqueta 20, 30 o 40, en caso de que i sea menor, igual o mayor que cero.
  45. ^ Sistemas informáticos Lahey, Inc. 2004.
  46. ^ Microsoft 2021.
  47. ^ Revista 1997.
  48. ^ z/OS 2.5.0 en la documentación de IBM 2021.
  49. ^ ab GCC, la colección de compiladores GNU 2021.
  50. ^ Fronczak y Lubbers 1974, pág. 226.
  51. ^ La declaración ALTER se consideró obsoleta en el estándar COBOL 1985 y se eliminó en 2002; consulte COBOL > Código automodificable
  52. ^ Van Tassel 2004.
  53. ^ Manual de sintaxis de Perl 2021.
  54. ^ GOTO para Java 2009.
  55. ^ Sextón 2012.
  56. ^ desde Hindle 2004.
  57. ^ desde Noack y col. 2015.
  58. ^ Gosling et al. (2005) A diferencia de C y C++, el lenguaje de programación Java no tiene sentencias goto; las etiquetas de sentencias identificadoras se utilizan con sentencias break (§14.15) o continue (§14.16) que aparecen en cualquier parte dentro de la sentencia etiquetada. Las palabras clave const y goto están reservadas, aunque actualmente no se utilizan. Esto puede permitir que un compilador Java produzca mejores mensajes de error si estas palabras clave de C++ aparecen incorrectamente en los programas.
  59. ^ Manual del lenguaje de programación Seed7 2021.
  60. ^ Manual de PHP 2021.
  61. ^ Wagner 2021.
  62. ^ "Instrucción GoTo - Visual Basic | Microsoft Learn". Microsoft Learn . 15 de septiembre de 2021 . Consultado el 25 de septiembre de 2023 .
  63. ^ La especificación del lenguaje de programación Go 2021.
  64. ^ Galler 1962, págs. 26-28, 197, 211.

Referencias

  • Allain, Alex (2019). "Cuándo usar Goto en C" . Consultado el 14 de noviembre de 2021 .
  • Andrews, Jeremy (13 de enero de 2003). «Linux: uso de goto en el código del núcleo». Archivado desde el original el 28 de noviembre de 2005. Consultado el 14 de noviembre de 2021 .
  • Brender, Ronald F. (2002). "El lenguaje de programación BLISS: una historia" (PDF) . Software: Práctica y Experiencia . 32 (10): 955–981. doi :10.1002/spe.470. S2CID  45466625.
  • Chisnall, David (2012). Manual de frases Objective-C . Addison-Wesley Professional. pág. 249. ISBN 978-0-321-81375-6.
  • Contieri, Maxi (2 de noviembre de 2021). "Código Olor 100 - Ir a". Maximiliano Contieri - Diseño de Software . Consultado el 14 de noviembre de 2021 .
  • Cozens, Simon (16 de abril de 2004). "Usos adecuados de goto". Archivado desde el original el 19 de marzo de 2011.
  • Dijkstra, Edsger W. (marzo de 1968). "Cartas al editor: Ir a la declaración considerada perjudicial" (PDF) . Comunicaciones de la ACM . 11 (3): 147–148. doi :10.1145/362929.362947. S2CID  17469809.
  • Fronczak, Edward J.; Lubbers, Clark E. (septiembre de 1974). MTS, Michigan Terminal System. Centro de Computación de la Universidad de Michigan. UOM:39015034770076.
  • Galler, Bernard A. (1 de enero de 1962). El lenguaje de las computadoras (PDF) . McGraw-Hill.
  • GCC, la colección de compiladores GNU (2021). «Etiquetas como valores: uso de la colección de compiladores GNU (GCC)». Gcc.gnu.org . Consultado el 13 de noviembre de 2021 .
  • Geisler, Sandra (2011). C All-in-One Desk Reference For Dummies (Referencia de escritorio todo en uno para principiantes) . John Wiley & Sons. Págs. 217–220. ISBN 978-1-118-05424-6.
  • Equipo de desarrollo de GNU Pascal (2005). «Estándares de codificación GNU Pascal». www.gnu-pascal.de . Free Software Foundation . Consultado el 10 de noviembre de 2021 .
  • Gosling, James ; McGilton, Henry (mayo de 1996). "El entorno del lenguaje Java". Oracle.com . Consultado el 22 de julio de 2014 .
  • GOTO para Java (6 de julio de 2009). «GOTO para Java». steik . Archivado desde el original el 15 de junio de 2012 . Consultado el 28 de abril de 2012 .
  • Hindle, Richie (1 de abril de 2004). "goto for Python". Entrian Solutions . Hertford, Reino Unido: Entrian Solutions Ltd . Consultado el 10 de noviembre de 2021 .
  • Tutorial de Java (28 de febrero de 2012). "Instrucciones de ramificación (Tutoriales de Java > Aprendizaje del lenguaje Java > Conceptos básicos del lenguaje)". Docs.oracle.com . Consultado el 10 de noviembre de 2021 .
  • Kelsey, R.; Clinger, W.; Rees, J.; et al. (agosto de 1998). "Informe revisado5 sobre el esquema de lenguaje algorítmico". Computación simbólica y de orden superior . 11 (1): 7–105. doi :10.1023/A:1010051815785. S2CID  14069423.
  • Knuth, Donald (1974). "Programación estructurada con instrucciones go to" (PDF) . Computing Surveys . 6 (4): 261–301. CiteSeerX  10.1.1.103.6084 . doi :10.1145/356635.356640. S2CID  207630080. Archivado desde el original (PDF) el 2017-07-17 . Consultado el 2017-01-26 .
  • Kozen, Dexter ; Tseng, Wei-Lung Dustin (julio de 2008). "El teorema de Böhm_Jacopini es falso, proposicionalmente" (PDF) . En Audebaud, Philippe; Paulin-Mohring, Christine (eds.). Matemáticas de la construcción de programas . 9.ª Conferencia Internacional MPC 2008. Apuntes de clase en informática. Vol. 5133. Marsella, Francia. pp. 177_192. CiteSeerX  10.1.1.218.9241 . doi :10.1007/978-3-540-70594-9_11. ISBN 978-3-540-70593-2.
  • Lahey Computer Systems, Inc (2004). "Declaración GOTO calculada (obsoleta)". Lahey Computer Systems, Inc. Archivado desde el original el 2016-05-26 . Consultado el 2021-11-10 .
  • Louden, Kenneth C.; Lambert, Kenneth A. (2012). Lenguajes de programación: principios y prácticas . Cengage Learning. pág. 422. ISBN 978-1-111-52941-3.
  • Manual del lenguaje de programación Seed7 (2021). «Características de Seed7» . Consultado el 10 de noviembre de 2021 .{{cite web}}: CS1 maint: nombres numéricos: lista de autores ( enlace )
  • McConnell, Steve (diciembre de 2004). Code Complete: A Practical Handbook of Software Construction, segunda edición (2.ª ed.). Microsoft Press. ISBN 978-0735619678.
  • Meyer, Bertrand (2009). Touch of Class: Aprendiendo a programar bien con objetos y contratos . Springer Science & Business Media. pág. 189. ISBN 978-3-540-92144-8.
  • Microsoft (2021). «Las instrucciones 'On GoTo' y 'On GoSub' ya no son compatibles». Microsoft . Consultado el 10 de noviembre de 2021 .
  • Noack, Sebastian; Blank, Douglas; Grainger, Thomas; spacewander (19 de septiembre de 2015). «snoack/python-goto: un decorador de funciones que reescribe el código de bytes para habilitar goto en Python». GitHub . Consultado el 10 de noviembre de 2021 .
  • Manual de sintaxis de Perl (2021). Ir a (Informe) . Consultado el 14 de noviembre de 2021 .
  • Manual de PHP (2021). "goto". PHP . Consultado el 13 de noviembre de 2021 .
  • Pitchford, Mark; Tapp, Chris (25 de febrero de 2013). "MISRA C:2012: muchas buenas razones para cambiar". Diseño electrónico . Consultado el 22 de julio de 2014 .
  • Ramshaw, L. (1988). "Eliminación de los elementos a los que se recurre mientras se preserva la estructura del programa". Revista de la ACM . 35 (4): 893–920. doi : 10.1145/48014.48021 . S2CID  31001665.
  • Regehr, John (4 de febrero de 2013). "Uso de Goto en código de sistemas: integrado en el ámbito académico". blog.regehr.org .
  • Roberts, Eric S. (marzo de 1995). "Salidas de bucle y programación estructurada: reabrir el debate". Boletín ACM SIGCSE . 27 (1): 268–272. doi : 10.1145/199691.199815 .
  • Rubin, Frank (marzo de 1987). ""GOTO Considered Harmful" Considered Harmful" (PDF) . Comunicaciones de la ACM . 30 (3): 195–196. doi :10.1145/214748.315722. S2CID  6853038. Archivado desde el original (PDF) el 20 de marzo de 2009.
  • Sahni, Sartaj; Cmelik, Bob (1995). Desarrollo de software en C. Silicon Press. pag. 135.ISBN 978-0-929306-16-2.
  • Sexton, Alex (2012). "El verano de Goto | Página oficial de Goto.js". Archivado desde el original el 25 de octubre de 2015.{{cite web}}: CS1 maint: URL no apta ( enlace )
  • Siedersleben, Johannes (2006). "Errores y excepciones: derechos y obligaciones". En Christophe Dony (ed.). Temas avanzados en técnicas de manejo de excepciones . Springer Science & Business Media. pág. 277. ISBN 978-3-540-37443-5.
  • Spinellis, Diomidis (27 de mayo de 2003). Lectura de código: la perspectiva del código abierto. Addison-Wesley Professional. pp. 43–44. ISBN 978-0-672-33370-5.
  • Preguntas de Stack Overflow (11 de junio de 2012). "¿Por qué "continuar" se considera una violación de C en MISRA C:2004?". Stack Overflow . Consultado el 10 de noviembre de 2021 .
  • Steele, Guy Lewis (enero de 1977). "Desmitificando el mito de las "llamadas a procedimientos costosas" o las implementaciones de llamadas a procedimientos consideradas dañinas o LAMBDA". Actas de la conferencia anual de 1977 sobre - ACM '77 . págs. 153–162. doi : 10.1145/800179.810196 . ISBN 9781450323086.S2CID 9807843  .
  • Stroustrup, Bjarne (9 de enero de 2012). "Discurso principal del día 1: Bjarne Stroustrup: estilo C ++ 11 | GoingNative 2012 | Canal 9". Canal9.msdn.com . Consultado el 10 de noviembre de 2021 .
  • Summit, Steve (1995). «Lista de preguntas frecuentes de comp.lang.c · Pregunta 17.10». C-faq.com . Consultado el 10 de noviembre de 2021 .
  • Especificación del lenguaje de programación Go (26 de julio de 2021). "Especificación del lenguaje de programación Go - El lenguaje de programación Go".
  • Torvalds, Linus (2016). "Estilo de codificación del núcleo de Linux". Documentación del núcleo de Linux . Consultado el 10 de noviembre de 2021 .
  • Van Tassel, Dennie (8 de julio de 2004). «Historia de las etiquetas en los lenguajes de programación» . Consultado el 4 de enero de 2011 .
  • Vine, Michael A. (2007). Programación en C para principiantes absolutos . Cengage Learning. ISBN 978-1-59863-634-5.
  • Wagner, Bill (2021). "Instrucción goto - Referencia de C#". docs.microsoft.com . Consultado el 9 de noviembre de 2021 .
  • Watt, David Anthony; Findlay, William (2004). Conceptos de diseño de lenguajes de programación . John Wiley & Sons. pág. 228. ISBN 978-0-470-85320-7.
  • Wehr, Jason (1997). "Ir a (asignado)". www.personal.psu.edu/jhm/f90/201.html . Consultado el 13 de noviembre de 2021 .
  • Williams, Tom (marzo de 2013). "Reglas de verificación para C: garantía de fiabilidad y seguridad". Revista RTC . 22 (3): 12–15 . Consultado el 10 de noviembre de 2021 .
  • z/OS 2.5.0 en Documentación de IBM (2021). "Instrucción goto calculada (extensión IBM)". IBM . Consultado el 13 de noviembre de 2021 . Este documento describe la sintaxis, la semántica y la implementación de IBM z/OS XL C/C++ de los lenguajes de programación C y C++. Para obtener una referencia estándar de C o C++ de uso general, consulte cppreference.com.{{cite web}}: CS1 maint: nombres numéricos: lista de autores ( enlace )
Obtenido de "https://es.wikipedia.org/w/index.php?title=Ir a&oldid=1248051767#GOTO_calculado"