He sido durante mucho tiempo bajo la impresión de que goto nunca debe ser usado si es posible. Mientras hojeaba libavcodec (escrito en C) el otro día, me di cuenta de usos múltiples de la misma. Es ventajoso utilizar goto en un lenguaje compatible con bucles y funciones? Si es así, ¿por qué?

InformationsquelleAutor Landon | 2008-08-23

25 Comentarios

  1. 233

    Hay un par de razones para el uso de la «goto» declaración de que soy consciente de (algunos han hablado de esto ya):

    Limpiamente salir de una función

    A menudo en una función, usted puede asignar recursos y la necesidad de salir en varios lugares. Los programadores pueden simplificar su código colocando el recurso de código de limpieza al final de la función, y todos los «puntos de salida» de la función goto a la limpieza de la etiqueta. De esta manera, usted no tiene que escribir el código de limpieza en cada «punto de salida» de la función.

    Salir de bucles anidados

    Si estás en un bucle anidado y la necesidad de salir de todos bucles, un goto puede hacer esto mucho más limpia y sencilla que romper las declaraciones y en el caso de los cheques.

    De bajo nivel mejoras de rendimiento

    Esto sólo es válido en el perf código crítico, pero goto ejecutar muy rápidamente y puede dar un impulso cuando se mueve a través de una función. Esta es una espada de doble filo, sin embargo, debido a que un compilador general, no puede optimizar el código que contiene gotos.

    Tenga en cuenta que en todos estos ejemplos, gotos están restringidas al ámbito de una sola función.

    • El camino correcto para salir de bucles anidados es refactorizar el bucle interno en un método independiente.
    • Bah. Eso es una carga de toro. La sustitución de goto con return es simplemente tonto. No se trata de «refactoring» nada, es «cambiar nombre» para que la gente que creció en un goto-suprimida el medio ambiente (es decir, todos nosotros) se sienten mejor acerca de la utilización de lo moralmente asciende a un goto. Yo prefiero ver el bucle donde puedo usarlo y ver un poco de goto, que de por sí es herramientas, de ver a alguien de haber movido el bucle en algún lugar relacionado sólo para evitar un goto.
    • Hay sitations donde gotos son importantes: por ejemplo, una excepción-menos C++ entorno. En Silverlight fuente tenemos decenas de miles (o más) de las instrucciones goto para la seguridad de la función existe a través del uso de las macros – clave de códecs multimedia y a menudo las bibliotecas de trabajo a través de los valores de retorno y nunca excepciones, y es difícil combinar estos errores los mecanismos de control en una sola rendimiento en el camino.
    • Vale la pena señalar que todos los break,continue,return son básicamente goto, solo en buen embalaje.
    • Para la limpia de salir de un punto de función, una alternativa es el uso de un do{/*code goes here*/}while(0); y el uso de break (o continuar :D) para salir de él. No hay etiquetas.
    • Ejemplo de uso de la etiqueta de salto en String.java: stackoverflow.com/questions/46586/goto-still-considered-harmful/…
    • exit() no funciona en un módulo de apache. Hice función de contenedor llamada exit()… que hizo un goto.
    • Una nota para limpiamente salir de una función: Chris habla sobre varios puntos de salida, esto se habría resuelto por tener un único punto de salida por la función.
    • No veo cómo do{....}while(0) se supone para ser una mejor idea que ir, excepto por el hecho de que funciona en Java.
    • El problema es que esto conduce a menudo bastante ilegible el código, ya sea con profundo de anidación o de un montón de «ayudante» de las variables. Salir temprano es increíble para mejorar la legibilidad – siempre que su lenguaje está optimizado para esto (por ejemplo, excepciones, (al menos parcialmente) la memoria administrada, …). Por supuesto, C#’s finally declaración que hace de esta una brisa – una mucho mejor «contenedor» para hacer cualquier limpieza requerida. Yo he visto un par de razones válidas para utilizar goto; en todos los casos, he tenido que reescribir la misma cosa como un bucle (aunque no era un bucle!) sólo para evitar la escritura de la temida goto. Que lastima legibilidad.
    • Estos la cacería de brujas siguen pasando al parecer. Absurdo que los estudiantes llevan con ellos las tonterías que se les había enseñado como evangelio. Es increíble las contorsiones de la gente va a ir a través de evitar el goto. Echa un vistazo a Jason comentario en la parte superior. Increíble….Yo estaba tan esperando este sentido habría que finalmente murió en la década de los 90.
    • Como a varios de retorno de evitación (oye), considere lo siguiente: en el punto en que desea salir, ¿por qué es mejor para el conjunto del estado y de la cascada de estado hacia abajo para un determinado punto de salida en lugar de simplemente volver? Usted obtener nada por esto. El solo argumento para que la celebración de cualquier agua era para tener pruebas y/o código de limpieza en el punto de salida. También, a veces perfiles es más fácil de hacer de esta manera. Pero las dos razones son muy débiles. Es mucho más fácil leer el código que devuelve realmente desde varios lugares en lugar de conjuntos de una cascada estado desde varios lugares!
    • Si sólo se trata de un problema sólo con los programadores 🙂 yo no sé acerca de las escuelas que he visto, pero la mayoría de los que he visto (y oído) son muy pesados en el «aprender las respuestas de la prueba» y muy ligero en «realmente a comprender el asunto». La primera lleva a aceptar las cosas como evangelio, el último a ser capaz de pensar acerca de si la «regla» tiene sentido o no. Si usted no entiende la experiencia, que no será muy probable para mejorarlo. Su experiencia en la enseñanza en Brasil es una aterradora y aleccionador leer – tinyurl.com/braziledu
    • Frank Rubin publicado una crítica de Dijkstra carta en el Marzo de 1987 CACM donde apareció bajo el título de ‘GOTO Considerado Nocivo» se Consideran Perjudiciales.[7] El Mayo de 1987 CACM impreso más respuestas, tanto a favor como en contra, bajo el título de ‘»GOTO Considera Perjudicial», Considerado Nocivo » Considera Perjudicial?.[8] el de Dijkstra propia respuesta a esta controversia se titula En un Poco Decepcionante la Correspondencia.[9]
    • Se le olvidó una muy buena razón: porque No Knuth utiliza goto en el Arte de La Programación de computadoras.
    • Además de la «limpia de salir de una función», hay más casos genéricos de múltiples caminos que conducen a un código común, tales como el último ejemplo en esta respuesta. Es una actuación orientada a la 4 forma de combinación de ordenación, el uso de declaraciones y si en lugar de un minheap para determinar la ejecución con el más pequeño elemento protagonista, y hay dos rutas de acceso a cada caso. Además, cuando se está acercando el final de la matriz, o cuando la concentración alcanza el final de una carrera, hay un desplegable para 3 forma de mezcla, luego de 2 vías, a continuación, copia el resto de la restante.

  2. 896

    Todo el mundo que es anti-goto de la cites, directa o indirectamente, Edsger Dijkstra GoTo Considera Perjudicial artículo para fundamentar su posición. Lástima que el de Dijkstra artículo tiene prácticamente nada que ver con la forma goto declaraciones se utilizan en estos días y por lo tanto lo que dice el artículo tiene poca o ninguna aplicabilidad de la programación moderna de la escena. El goto-menos meme verges ahora en una religión, en sus escrituras, dictada por la alta, sus sumos sacerdotes y el rechazo (o peor) de la percepción de los herejes.

    Vamos a poner el de Dijkstra papel en contexto para arrojar un poco de luz sobre el tema.

    Cuando Dijkstra escribió su papel de los idiomas más populares de la época, fueron no estructurados de procedimiento, como BASIC, FORTRAN (el anterior dialectos) y de diversos lenguajes de ensamblado. Es muy común para las personas que utilizan el más alto nivel de idiomas para saltar todo su código base en torcido, retorcido hilos de ejecución que dio lugar al término «código espagueti». Usted puede ver esto por salto de más a la clásica Caminata de juego escrito por Mike Mayfield y tratando de averiguar cómo funcionan las cosas. Tome unos momentos para mirar que más.

    ESTE es «el desenfrenado uso de la declaración» que Dijkstra fue despotricar contra de su papel en 1968. ESTE es el ambiente que se vivió en el que le llevó a escribir ese artículo. La capacidad de saltar a cualquier lugar que desee en su código en cualquier punto de que le gustaba era lo que estaba criticando y exigiendo ser detenido. Comparando eso con la anemia de los poderes de goto en C o en otra más lenguas modernas es simplemente risible.

    Ya puedo escuchar la elevación de los cantos de los cultores que se enfrentan a los herejes. «Pero,» van a cantar, «puede hacer que el código sea muy difícil de leer, con goto en C.» Ah, sí? Usted puede hacer que el código sea muy difícil de leer, sin goto así. Como este:

    #define _ -F<00||--F-OO--;
    int F=00,OO=00;main(){F_OO();printf("%1.3f\n",4.*-F/OO/OO);}F_OO()
    {
    _-_-_-_
    _-_-_-_-_-_-_-_-_
    _-_-_-_-_-_-_-_-_-_-_-_
    _-_-_-_-_-_-_-_-_-_-_-_-_-_
    _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
    _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
    _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
    _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
    _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
    _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
    _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
    _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
    _-_-_-_-_-_-_-_-_-_-_-_-_-_
    _-_-_-_-_-_-_-_-_-_-_-_
    _-_-_-_-_-_-_-_
    _-_-_-_
    }

    No goto a la vista, por lo que debe ser fácil de leer, ¿verdad? O qué tal esta:

    a[900];     b;c;d=1     ;e=1;f;     g;h;O;      main(k,
    l)char*     *l;{g=      atoi(*      ++l);       for(k=
    0;k*k<      g;b=k       ++>>1)      ;for(h=     0;h*h<=
    g;++h);     --h;c=(     (h+=g>h     *(h+1))     -1)>>1;
    while(d     <=g){       ++O;for     (f=0;f<     O&&d<=g
    ;++f)a[     b<<5|c]     =d++,b+=    e;for(      f=0;f<O
    &&d<=g;     ++f)a[b     <<5|c]=     d++,c+=     e;e= -e
    ;}for(c     =0;c<h;     ++c){       for(b=0     ;b<k;++
    b){if(b     <k/2)a[     b<<5|c]     ^=a[(k      -(b+1))
    <<5|c]^=    a[b<<5      |c]^=a[     (k-(b+1     ))<<5|c]
    ;printf(    a[b<<5|c    ]?"%-4d"    :"    "     ,a[b<<5
    |c]);}      putchar(    '\n');}}    /*Mike      Laman*/

    No goto allí. Por lo tanto, debe ser legible.

    ¿Cuál es mi punto de vista con estos ejemplos? No es el lenguaje de las características que hacen ilegible, tanto el código. No es la sintaxis que hace. Es malo que los programadores que causa esto. Y los malos programadores, como se puede ver en que punto anterior, puede hacer cualquier característica del lenguaje ilegible e inutilizable. Como el for bucles hasta allí. (Usted puede ver, a la derecha?)

    Ahora, para ser justos, algunas construcciones de lenguaje son más fáciles de abusar de los demás. Si eres un programador de C, sin embargo, me gustaría pares mucho más de cerca en aproximadamente el 50% de los usos de #define mucho antes de que me gustaría ir en una cruzada contra goto!

    Así que, para aquellos que se han molestado en leer este momento, hay varios puntos clave a tener en cuenta.

    1. Dijkstra papel en goto declaraciones fue escrito para un entorno de programación donde goto fue un mucho
      potencialmente más perjudicial que es en la mayoría de las lenguas modernas que no son un ensamblador.
    2. Automáticamente tirar todos los usos de goto debido a esto es tan racional como diciendo: «he intentado
      para divertirse de una vez, pero no me gusta así que ahora yo estoy en contra de ella».
    3. Hay usos legítimos de la moderna (anemia) goto declaraciones en el código que no puede ser adecuadamente
      reemplazadas por otras construcciones.
    4. Hay, por supuesto, ilegítimo usos de las mismas declaraciones.
    5. Hay, también, ilegítimo usos de las modernas declaraciones de control como el «godo» abominación donde siempre-falso do es rota de uso de break en lugar de un goto. Estos a menudo son peores que el uso juicioso de goto.
    • «Me gustaría pares mucho más de cerca en alrededor de un 50% del uso de #define mucho antes de que me gustaría ir en una cruzada contra goto!» <– De hecho, usted puede hacer ambas cosas!
    • … @sgm ya ha dicho de ella: que es una enorme pila de errores lógicos. Solo quiero comentar una cosa: Usted dijo que se han utilizado goto 3 veces en los últimos x años – dime, ¿cómo se compara esto con alguna otros «de propósito general» característica del lenguaje (I excluir explícitamente especializados, sin embargo, a veces es necesario características del lenguaje como volatile que algunas personas no necesitan)? ¿No es extraño que una de propósito general característica del lenguaje que se usa muy poco en el código? Para mí, que es una fuerte indicación de que goto no aporta mucho a la mesa. I. e., que es defectuoso. Vaya usted a saber.
    • Rudolph: permítanme parafrasear tu comentario para demostrar que el defecto en su forma de pensar. «Yo excluir explícitamente exactamente el tipo de características del lenguaje que socavaría mi llamado ‘argumento’, entonces, ¿cómo justificar esta otra característica del lenguaje?»
    • MI OPINIÓN correcta: Que no es para nada como lo que he dicho. Sólo porque dos oraciones sintácticamente similares no hacen semánticamente equivalentes. volatile no es redundante (es decir, no puede ser replicado lo contrario) especial característica del lenguaje. goto es de propósito general, y completamente ortogonales, con otras características del lenguaje.
    • -1 para «Otras cosas que están mal, así que goto no puede ser» argumentos. Estoy bastante seguro de que la gente argumentando en contra de goto también sería contra el código que aparece.
    • «Hay usos legítimos de la moderna (anemia) goto en el código que no puede ser adecuadamente sustituido por otras construcciones.» Se puede poner un ejemplo?
    • La escritura de la cola-recursivo de optimización en C, por ejemplo. Esto viene en la implementación de un lenguaje funcional intérpretes/tiempos de ejecución, pero es representativa de una interesante categoría de problemas. La mayoría de los compiladores escrito en C hacer uso de goto por esta razón. Es un nicho de uso que no ocurre en la mayoría de las situaciones, por supuesto, pero en las situaciones en que se pide se hace un mucho de sentido a su uso.
    • Usted puede hacer cola recursividad en C por sólo envolver el cuerpo de la función en un bucle para int f(int a, int b) { if (a < 10) return a; return f(a + b, b); } se convierte en int f(int a, int b) { for (;;;) { if (a < 10) { return a; } a += b; continue; } } donde la cola de llamadas se vuelven a escribir para reasignar los parámetros y continue a la parte superior del bucle.
    • ¿Por qué todo el mundo habla acerca de Dijkstra «Ir a considerarse perjudiciales» de papel sin mencionar Knuth la respuesta es, «programación Estructurada con ir a las declaraciones»?
    • es bastante descarado hombre de paja […]» Él sarcásticamente el uso de una falsa dicotomía para mostrar por qué el estigma es ilógico. Un Strawman es una falacia lógica donde intencionalmente falsear la posición del oponente, para hacer parecer que su posición es fácilmente derrotado. E. g. «Los ateos son sólo ateo porque odian a Dios». Una falsa dicotomía es cuando usted asume el extremo opuesto es verdadera cuando al menos una posibilidad adicional existe (es decir, negro y blanco). E. g. «Dios odia a los homosexuales, por lo tanto, él ama a los heteros.».
    • no puede haber sido el término correcto, pero sarcástico o no, una falsa dicotomía es un falaz argumento, sin embargo, este cartel está tratando de justificar su punto de vista.
    • Estás leyendo demasiado profundo en algo que ni siquiera existe. Es sólo una verdadera falacia lógica si la persona que utiliza honestamente cree que tiene sentido lógico. Pero él lo dijo sarcásticamente, indicando claramente que él sabe que es ridículo, y así es como él se lo estaba mostrando. Él no está «utilizando para justificar su punto de vista»; que lo utiliza para mostrar por qué es ridículo decir que gotos la realización automática de código en los espaguetis. I. e. usted puede escribir mierda código sin gotos. QUE es su punto de vista. Y sarcástico falsa dicotomía es su método de ilustrar en forma humorística.
    • I. e. sí, él utilizó una falacia lógica, intencionalmente, para guiar al lector a una válida conclusión lógica. Qué tiene de malo eso? ¿Cuál es tu punto? Es su posición de alguna manera «menos válido» porque de eso? Si es así, entonces tu argumento es un real falsa dicotomía. Pensar en ello. Estás diciendo básicamente que una falacia lógica no es válido independientemente del contexto. Y que si uno la usa, incluso si lo utilizan como una ilustración, entonces son «automáticamente equivocado». Básicamente, Falacia Lógica = Mal, y No hay Falacia Lógica = a Derecha. En blanco y negro. No hay zonas grises. Esa es una falsa dicotomía.
    • He leído el artículo por qué no contribuir en forma y saltó por aquí. De hecho estoy totalmente de acuerdo ‘no es el lenguaje (goto) que hace que el software sea legible y fácil de mantener, pero la forma de usarlo’. He sido denostado en los mediados de los años ochenta cuando escribí MUY legible y mantenible código mediante el uso de goto sólo PORQUE me acaba de pasar. Yo solía ir a simular funciones privadas combinado con datahidding en FORTRAN. Varios años más tarde, la gente comenzó a entender por QUÉ me programmaed igual que como las cosas llegaron a ser comunes a otros idiomas. Dijkstra artículo centrado en la manera de goto se utilizó en ese momento
    • Para puntos de bonificación, usted debe poner int en frente de F_OO(); en main() y emplear la más complejos de analizar. Tal vez envuelto en una definición…
    • -1 para hacer un gran argumento de por qué el de Dijkstra comentario no es aplicable, olvidando a mostrar cuáles son las ventajas de goto son en realidad (que es la pregunta publicado)
    • ^ como owlstead dijo. Yo no -1, pero el OP estaba preguntando CUANDO goto es útil en un lenguaje estructurado. Esto no da ningún ejemplo de que cuando goto es útil, ni siquiera un enlace a estos ejemplos. También, re punto #3: que depende del idioma, y en cómo uno pesa trade-offs. Por lo general una «mejor» solución es factor de pequeñas funciones, por lo que no hay una única función tiene un complejo de control de flujo. El único discutible es si es aceptable el uso de varias devoluciones en tales funciones. Un par de personas en lugar de ir a un común punto de retorno. Otros utilizan banderas & pruebas.
    • que se metió con calzador. Escribir un protocolo de decodificador con for/while y, a continuación, con goto…
    • tal vez, pero no veo la forma en que lo relevante a la cola de la recursividad en el código generado.
    • Es decir, evitando la rama misprediction.
    • Yo no lo entiendo. Ambos goto y for (;;;) compilar incondicional, salta. Cómo es una mejor w.r.t. rama de la predicción?
    • a qué te refieres for (;;) ?
    • Por CIERTO, esta respuesta de @JUSTMYcorrectOPINION, es en el clavo. La caza de brujas en contra de goto acaba de llegar a la parada. Voy a ir más allá y hacer un reclamo similar que la caza de brujas en contra de varias devoluciones de funciones/métodos deberían igualmente desaparece, así como el uso de la niñera-ismos como if (0==x) en C para evitar accidental de asignación. La gente, es 2015, y todavía estamos engañados con esta tontería?
    • Sí, me refería for (;;).
    • -1 por no especificar una sola razón por la que sería ventajoso utilizar goto en un lenguaje compatible con bucles y funciones.
    • «‘gran expectación». Es una contracción de «disminuido». Al menos, si usted quiere que sus escritos parecen ser situado en un contexto tan antigua como la de «GoTo Considera Perjudicial».
    • La única razón por la que estoy abajo-la votación de esta respuesta es porque es muy subjetivamente respondió. Los ejemplos de código son de las competiciones donde ‘inteligente’ de los programadores deliberadamente escribir código ofuscado. Por favor reformular su respuesta, para quitar la lógica del engaño, y usted consigue mi upvote.
    • su argumento utiliza reductio ad absurdem–¿te das cuenta que los ejemplos que dio fueron de un concurso para escribir, para leer el código?????? -1

  3. 151

    Obedecer las mejores prácticas a ciegas no es una práctica recomendada. La idea de evitar la goto declaraciones como la principal forma de control de flujo es evitar la producción de ilegible código espagueti. Si se usa con moderación en los lugares adecuados, a veces puede ser la más simple, la forma más clara de expresar una idea. Walter Brillante, el creador de la Zortech compilador de C++ y el lenguaje de programación D, se utiliza con frecuencia, pero con prudencia. Incluso con la goto declaraciones, su código es perfectamente legible.

    Línea de base: Evitar goto por el bien de evitar goto es inútil. Lo que realmente se quiere evitar es la producción de código ilegible. Si su gotocargados de código es legible, entonces no hay nada de malo con ello.

  4. 36

    Desde goto hace razonar sobre el flujo de un programa duro1 (aka. «código espagueti»), goto es generalmente utilizado para compensar la falta de características: El uso de goto en realidad puede ser aceptable, pero sólo si el idioma no es una forma más estructurada, con la variante para obtener el mismo objetivo. Tome Duda el ejemplo:

    La regla con goto que utilizamos es que goto está bien para saltar hacia adelante a una sola salida de limpieza de punto en una función.

    Esto es cierto pero sólo si el lenguaje no permite el control estructurado de excepciones con el código de limpieza (como RAII o finally), que hace el mismo trabajo mejor (ya que está especialmente construido para hacerlo), o cuando hay una buena razón para no emplear el control estructurado de excepciones (pero usted nunca tendrá este caso, excepto en un nivel muy bajo).

    En la mayoría de los otros idiomas, el único uso aceptable de goto es salir de bucles anidados. Y aún así, es casi siempre mejor para levantar el bucle exterior, en un propio método y el uso return lugar.

    Aparte de eso, goto es una señal de que no se ha reflexionado sobre el particular pieza de código.


    1 idiomas Modernos que apoyan goto aplicar algunas restricciones (por ejemplo, goto no puede saltar dentro o fuera de funciones), pero el problema sigue siendo fundamentalmente el mismo.

    Por cierto, el mismo es, por supuesto, también se aplica para las otras características del lenguaje, en particular la mayoría de las excepciones. Y por lo general hay reglas estrictas en lugar de sólo usar estas características en el lugar indicado, tales como la regla de no usar excepciones para controlar no excepcionales de flujo del programa.

    • Solo por curiosidad, aquí, pero lo que sobre el caso de usar gotos para limpiar el código. Por la limpieza, es decir, no sólo la desasignación de memoria, pero también, decir que el registro de errores. Estaba leyendo a través de un montón de puestos, y al parecer, nadie escribe código que imprime los registros.. hmm?!
    • shiva: no estoy seguro de que usted vea un beneficio de goto aquí. RAII y control de errores estructurado son poderosos mecanismos para facilitar el registro. Es cierto que no se hace lo suficiente, porque siempre abarrota el código.
    • «Básicamente, debido a goto defectuosas de la naturaleza (y creo que esto es tema de controversia)» -1 y he dejado de leer allí.
    • La advertencia contra goto viene de la programación estructurada de la época, donde los rendimientos se consideró también el mal. Movimiento de bucles anidados en una función de oficios de un «mal» para el otro, y se crea una función que no tiene razón de existir (fuera de «me permitió evitar el uso de goto!»). Es cierto que el goto es la herramienta más poderosa para la producción de espaguetis código si se utiliza sin restricciones, pero esta es una aplicación perfecta para ello, sino que simplifica el código. Knuth argumentado para este uso, y Dijkstra dijo «no caigan en la trampa de creer que soy terriblemente dogmática acerca de goto».
    • finally? Así mediante el uso de excepciones para otras cosas que el manejo de errores es bueno, pero el uso de goto es malo? Creo que excepciones son bastante honor a su nombre.
    • es para la limpieza después de que se produce una excepción. Cómo es que el abuso?
    • Sólo estoy diciendo que hay casos donde RAII no es una buena solución y es la limpieza, pero no el manejo de errores. A continuación, mediante el uso de excepciones, sólo para evitar goto es peor estilo de goto mismo en mi humilde opinión. Mediante el uso de excepciones para el control de errores es sólo la cosa para hacer, por supuesto, supongo que nadie podría argumentar en contra de eso.
    • Así que usted está simplemente equivocado entonces. Hay un amplio consenso de que RAII es perfectamente adecuado para este. De hecho, muchos de C++ moderno modismos de usarlo. Se parecen bajo la impresión de que usted necesita para lanzar una excepción a hacer RAII utilizable pero claro que esto es incorrecto. Usted simplemente regresar antes de la mayoría de las funciones y dejar RAII cuidar de la limpieza – excepciones no están involucrados en eso.
    • Agradezco tu alemán franqueza pero creo que un poco más de precaución en la evaluación de lo que en realidad significaba que habría sido apropiado. Yo no confundir RAII y excepciones y yo no implican que RAII no es nada, pero perfecto para la mayoría de los casos. Todo lo que quería decir en mi anterior comentario era lo que esta respuesta resume muy bien stackoverflow.com/a/18507873/1050373.
    • La respuesta dice que el uso de RAII exactamente de la manera que he descrito. Yo no sueño con el uso de excepciones en ese escenario (a menos por supuesto que en realidad hizo que la semántica sentido). No puedo imaginar una situación en la que yo podría nunca llegar al punto 3 en la respuesta – estoy bastante seguro de que nunca tengo, para una cosa. Si alguna vez me hago la promesa de que usted utilice goto en lugar de la do…while construir. 😉
    • Por ejemplo, Java también tiene la etiqueta se rompe, que se puede utilizar en lugar de goto para salir de bucles anidados. La etiqueta se rompe no están muy bien, pero son menos controvertido que goto declaraciones.
    • ¿en qué idioma? Try/Catch/Finally en C# (o de otro perezoso GC gustaría idioma) cubre cada caso, soy consciente de. En C++ (o en otro idioma con un estricto control de memoria), RAII es la solución aceptada.
    • en los casos en los que me encuentro (sobre una base diaria), la creación de una función «que no tiene razón de existir» se la mejor solución. Razón: se elimina el detalle de las funciones de nivel superior, de tal manera que el resultado ha de fácil lectura, de control de flujo. Yo personalmente no encontrar situaciones en las que un goto produce la más legible el código. Por otro lado, yo uso varias devoluciones, en funciones simples, donde alguien podría prefieren ir a un solo punto de salida. Me encantaría ver a contra-ejemplos donde goto es más legible que la refactorización en nombre de las funciones.
    • para aclarar cómo me refactorizar: Normalmente es la más legible estilo es reemplazar complicado pruebas por una sola función, y acciones complicadas por otra función. Esto podría convertir una enorme función en MUCHOS pedazos pequeños, pero el nivel superior método debe ser fácil de leer, y no debería necesitar ningún gotos. Todos los gotos se han convertido en la condición de las pruebas, o de lo contrario adicionales devuelve en una de las pequeñas piezas. (Y si usted prefiere gotos DENTRO de uno de esos pequeños pedazos, para evitar que varias devoluciones, que es un defendible estilo). Yo no conozco a ninguna de las situaciones que no se ajustan a este enfoque.
    • Wow. Este es un hilo viejo! @KonradRudolph Hay varias respuestas en este hilo que responder a sus preguntas mejor que puedo. stackoverflow.com/a/24476/11018 stackoverflow.com/a/21360087/11018
    • C era el idioma que hablaba. Entonces de nuevo, eso fue hace 5 años! 🙂
    • No alcancé a hacer una pregunta. Los hilos que has vinculado revelan nada nuevo. En particular, (1) salir de las funciones ya descritas en mi respuesta; (2) salir de bucles anidados ya mencionado en mi respuesta; (3) mejora de la velocidad es un argumento cuestionable. Soy consciente de Knuth del ensayo sobre el tema, y sus ejemplos de un caso donde goto es la solución más rápida. Pero en la práctica no he encontrado una situación aún donde goto mejor rendimiento (y yo tenía escrito mi cuota de alto rendimiento de código).

  5. 35

    Bueno, hay una cosa que es siempre peor que goto's; extraño el uso de otros programflow operadores para evitar un goto:

    Ejemplos:

        //1
    try{
    ...
    throw NoErrorException;
    ...
    } catch (const NoErrorException& noe){
    //This is the worst
    } 
    //2
    do {
    ...break; 
    ...break;
    } while (false);
    //3
    for(int i = 0;...) { 
    bool restartOuter = false;
    for (int j = 0;...) {
    if (...)
    restartOuter = true;
    if (restartOuter) {
    i = -1;
    }
    }
    etc
    etc
    • do{}while(false) Creo que puede ser considerada idiomáticas. No está permitido de acuerdo 😀
    • Si es «idiomáticas», eso es sólo porque el de la anti-goto culto. Si miras muy de cerca, te das cuenta de que es sólo una manera de decir goto after_do_block; sin realmente decir eso. De lo contrario…un «bucle», que se ejecuta exactamente una vez? Yo diría que eso es abuso de estructuras de control.
    • Eding Hay una excepción a su punto. Si alguna vez has hecho algo de C/C++ programación y tuvo que usar #define, usted sabe, que do{}while(0) es uno de los estándares para la encapsulación de varias líneas de código. Por ejemplo: #define do{memcpy(a,b,1); algo++;}while(0) es más seguro y mejor que #define memcpy(a,b,1); algo++
    • Usted acaba muy muy bien demostrado cómo #defines son muchas, muchas veces, mucho peor que el uso de goto de vez en cuando 😀
    • De verdad? Bien #define y goto son diferentes cosas para diferentes propósitos. Definir funciona perfectamente bien cuando se utiliza para las constantes. En algunas aplicaciones, el uso de definir para el código es la única forma. Parece que no ha crecido todavía lo suficiente para ver este tipo de aplicaciones.
    • Eso es muy posible. Todavía no lo hace una buena práctica, aunque es supuestamente el único camino 🙂
    • +1 para una buena lista de las maneras en que la gente trata de evitar los gotos, a un extremo; he visto menciones de estas técnicas en otros lugares, pero este es un gran, sucinta, de la lista. Reflexionar sobre por qué, en los últimos 15 años, mi equipo nunca ha necesitado alguna de esas técnicas, ni usado gotos. Incluso en una aplicación cliente/servidor con cientos de miles de líneas de código, por varios programadores. C#, java, PHP, python, javascript. Cliente, el servidor y el código de la aplicación. No hago alarde, ni hacer proselitismo para una posición, sólo verdaderamente curiosa de por qué algunas personas se enfrentan a situaciones que piden para gotos como solución más clara, y otros no…
    • FYI, la principal técnica que usamos para evitar tanto complicado de control de flujo y gotos, es una disposición a romper en muchas pequeñas rutinas, y permitir que esas rutinas para contener varias devoluciones (porque son lo suficientemente pequeños para ser fáciles de entender, depurar y modificar). La solución alternativa es el uso de banderas para modificar lazo de control. Pero nunca he visto que degenere en uno de los formularios que se muestran allí. Y acepto que algunas personas prefieren gotos a varias devoluciones, incluso en los más simples rutinas.

  6. 28

    En C# interruptor de declaración haces no permitir la caída-a través de. Así goto se utiliza para transferir el control a un determinado interruptor caso de la etiqueta o el por defecto etiqueta.

    Por ejemplo:

    switch(value)
    {
    case 0:
    Console.Writeln("In case 0");
    goto case 1;
    case 1:
    Console.Writeln("In case 1");
    goto case 2;
    case 2:
    Console.Writeln("In case 2");
    goto default;
    default:
    Console.Writeln("In default");
    break;
    }

    Edit: Hay una excepción en «no caer» a través de la regla. Caer es permitido si el caso de la declaración no tiene ningún código.

    • Interruptor de caída a través de está apoyado en .NET 2.0 – msdn.microsoft.com/en-us/library/06tc147t(VS.80).aspx
    • Sólo si el caso no tiene un cuerpo de código. Si no dispone de código, a continuación, usted debe usar el goto palabra clave.
    • Esta respuesta es tan divertido – C# eliminado otoño-porque muchos lo ven como perjudiciales, y en este ejemplo se utiliza goto (también visto como nocivo por muchos) para reactivar la original, supuestamente perjudiciales, comportamiento, PERO el resultado global es, en realidad, menos dañinos (porque el código deja claro que la fallthrough es intencional!).
    • Sólo porque una palabra se escribe con las letras de Ir A no hacer un goto. Este caso presentado no es un goto. Se trata de una instrucción switch para construir fallthrough. Entonces de nuevo, yo realmente no sé C# muy bien, así que puedo estar equivocado.
    • Bueno, en este caso es un poco más de caída a través de (porque se puede decir goto case 5: cuando estamos en el caso 1). Parece Konrad Rudolph respuesta es correcta aquí: goto está compensando por una característica que falta (y es menos clara que la característica real sería). Si lo que realmente queremos es que la caída -, tal vez la mejor manera predeterminada sería no caer, pero algo como continue para solicitar explícitamente.
    • Por supuesto, muchos programadores consideran interruptor de caída a través de tan malos como goto, por la misma razón: se puede hacer que el código sea difícil de razonar acerca de. Y he descaradamente utilizado para simplificar el código de antes. 🙂 Sólo porque una sierra eléctrica es peligroso no significa que deje fuera de su kit de herramientas.
    • Este se un legítimo ejemplo de una situación donde goto puede ser apropiado. no Obstante, en el mundo real, los casos que he encontrado a lo largo de los últimos diez años de C# de codificación, nunca he encontrado una situación en la que yo considere que esta es la solución más limpia. Alternativa #1: de llamadas a funciones comunes. case 0: f0(); f1(); f2();, case 1: f1(); f2(); etc. Alternativa #2: de una serie de ifs: if (value==0) f(0);, if (value==0 || value==1) f(1); etc. Concedido, en este ejemplo inventado el gotos podría ser más clara. Pero en situaciones de la vida real, yo lo dudo.

  7. 14

    #ifdef TONGUE_IN_CHEEK

    Perl tiene un goto que le permite implementar el pobre hombre de la cola de llamadas. 😛

    sub factorial {
    my ($n, $acc) = (@_, 1);
    return $acc if $n < 1;
    @_ = ($n - 1, $acc * $n);
    goto &factorial;
    }

    #endif

    Bien, así que no tiene nada que ver con C goto. Más en serio, estoy de acuerdo con los otros comentarios sobre el uso de goto de la limpieza, o para la aplicación de Duff del dispositivo, o similares. Todo acerca del uso, no abusar.

    (El mismo comentario se puede aplicar a longjmp, excepciones, llamada/cc, y similares—ellos tienen usos legítimos, pero que se puede abusar fácilmente. Por ejemplo, lanzar una excepción puramente para escapar de un anidadas estructura de control, bajo completamente no-circunstancias excepcionales.)

    • Creo que esta es la única razón para usar goto en Perl.
  8. 12

    He escrito más de un par de líneas de lenguaje ensamblador a través de los años. En última instancia, cada lenguaje de alto nivel compila abajo para gotos. Bueno, les llaman «ramas» o «saltos» o cualquier otra cosa, pero son gotos. Cualquiera puede escribir goto-menos ensamblador?

    Ahora claro, se puede señalar a un Fortran, C o BASIC programador que para ejecutar riot con gotos es una receta de espaguetis a la boloñesa. La respuesta sin embargo no es para evitarlos, pero para usar con cuidado.

    Un cuchillo puede ser utilizado para preparar la comida, libre de alguien, o matar a alguien. Qué hacemos sin cuchillos por el temor de la última? Del mismo modo goto: utiliza sin cuidado lo impide, se utilizan cuidadosamente ayuda.

    • Tal vez usted quiere saber por qué creo que esto es fundamentalmente equivocado en stackoverflow.com/questions/46586/…
    • Cualquiera que avanza el «todo compila abajo a JMP de todos modos!» argumento básicamente no entiende el punto detrás de la programación en un lenguaje de alto nivel.
    • Todo lo que realmente necesita es restar-y-rama. Todo lo demás es para la comodidad o el rendimiento.
  9. 8

    Echa un vistazo a Cuando el Uso De Goto Cuando la Programación en C:

    Aunque el uso de goto es casi siempre una mala práctica de programación (seguramente usted puede encontrar una mejor manera de hacer XYZ), hay momentos en los que realmente no es una mala elección. Incluso algunos podrían argumentar que, cuando es útil, es la mejor opción.

    Más de lo que tengo que decir acerca de goto en realidad sólo se aplica a C. Si usted está usando C++, no hay ninguna buena razón para el uso de goto en lugar de excepciones. En C, sin embargo, usted no tiene el poder de un mecanismo de manejo de excepciones, así que si quieres separar el manejo de errores del resto de la lógica del programa, y quieres evitar la reescritura de código de limpieza varias veces a lo largo de su código, entonces goto puede ser una buena opción.

    ¿A qué me refiero? Podría tener algo de código que se parece a esto:

    int big_function()
    {
    /* do some work */
    if([error])
    {
    /* clean up*/
    return [error];
    }
    /* do some more work */
    if([error])
    {
    /* clean up*/
    return [error];
    }
    /* do some more work */
    if([error])
    {
    /* clean up*/
    return [error];
    }
    /* do some more work */
    if([error])
    {
    /* clean up*/
    return [error];
    }
    /* clean up*/
    return [success];
    }

    Esto está bien hasta que te das cuenta de que necesita cambiar su código de limpieza. Entonces usted tiene que ir a través y hacer 4 cambios. Ahora, usted puede decidir que usted puede encapsular todos los de la limpieza en una sola función; que no es una mala idea. Pero esto no significa que usted tendrá que tener cuidado con los punteros — si usted planea liberar un puntero en su función de limpieza, no hay manera de configurarlo para que, a continuación, seleccione NULL a menos que se pasa un puntero a un puntero. En muchos de los casos, usted no va a utilizar ese puntero de nuevo de todos modos, por lo que no puede ser una preocupación importante. Por otro lado, si se añade en un nuevo puntero, identificador de archivo, o de otra cosa que de las necesidades de limpieza, entonces usted necesitará cambiar su función de limpieza de nuevo; y entonces usted necesitará cambiar los argumentos a la función.

    Mediante goto, será

    int big_function()
    {
    int ret_val = [success];
    /* do some work */
    if([error])
    {
    ret_val = [error];
    goto end;
    }
    /* do some more work */
    if([error])
    {
    ret_val = [error];
    goto end;
    }
    /* do some more work */
    if([error])
    {
    ret_val = [error];
    goto end;
    }
    /* do some more work */
    if([error])
    {
    ret_val = [error];
    goto end;
    }
    end:
    /* clean up*/
    return ret_val;
    }

    La ventaja aquí es que el código siguiente final tiene acceso a todo lo que se necesita para realizar la limpieza, y se ha logrado reducir el número de puntos de cambio considerablemente. Otro beneficio es que hemos pasado de tener múltiples puntos de salida para la función de uno solo; no hay ninguna posibilidad de que usted accidentalmente de retorno de la función sin limpiar.

    Por otra parte, desde goto sólo se utiliza para saltar a un único punto, no es como si usted está creando una masa de espagueti código de saltar hacia atrás y adelante en un intento de simular las llamadas de función. Más bien, goto en realidad ayuda a escribir más código estructurado.


    En una palabra, goto siempre debe ser usado con moderación, y como último recurso, pero hay un tiempo y un lugar para él. La pregunta no debería ser «¿tiene usted el uso de» pero «es que es la mejor opción» para usarlo.

  10. 7

    Una de las razones goto es malo, además de estilo de codificación es que usted puede utilizar para crear la superposición de, pero no anidada bucles:

    loop1:
    a
    loop2:
    b
    if(cond1) goto loop1
    c
    if(cond2) goto loop2

    Esto crearía la extraña, pero posiblemente legales de flujo de control de la estructura en la que una secuencia como (a, b, c, b, a, b, a, b, …) es posible, lo que hace que el compilador de hackers infeliz. Al parecer hay un número de inteligente de optimización de trucos que se basan en este tipo de estructura no se produzca. (Debo revisar mi copia de el dragón libro…) El resultado de esto podría (usando algunos compiladores) que otras optimizaciones no está listo para el código que contiene gotos.

    Puede ser útil si usted saber simplemente, «oh, by the way», que pasa a persuadir a que el compilador emite un código más rápido. Personalmente, prefiero tratar de explicar al compilador sobre lo que es probable y lo que no antes de que el uso de un truco como el de goto, pero podría decirse, que también podría intentar goto antes de hacking ensamblador.

    • Bueno…me lleva de vuelta a los días de programación FORTRAN en una información financiera de la empresa. En el año 2007.
    • Cualquier estructura de la lengua puede ser objeto de abuso en las formas que hacerla ilegible o mal desempeño.
    • El punto no es acerca de la legibilidad, o rendimiento pobre, pero los supuestos y garantías sobre el flujo de control gráfico. Cualquier abuso de goto sería más de rendimiento (o de legibilidad).
    • Yo diría que una de las razones goto es útil es que permite construir bucles como este, que requeriría un montón de lógica contorsiones de otra manera. Yo sería más argumentan que si el optimizador no sabe cómo volver a escribir esto, entonces bien. Un bucle como este no debería ser hecho por el rendimiento o mejorar la legibilidad, pero debido a que es exactamente el orden en que las cosas tienen que suceder. En cuyo caso yo no particularmente quiero el optimizador jodía con ella.
    • Muchos problemas de los dominios tienen una cantidad considerable de «no-» cuidado de los aspectos de su conducta que pudiera encajar un parcial superposición de diseño de bucle, pero también podría caber un convencionales nested-diseño de bucle. Históricamente, en goto lenguajes basados en las cosas fueron escritas con parciales de superposición estilo incluso cuando una nested-diseño de bucle hubiera sido tan buena y necesaria acerca de la misma cantidad de código. Esa es una de las razones por la animadversión en contra de gotos. Por otro lado, para algunos de los raros problema dominios donde peculiar comportamiento del lazo es un aspecto clave de lo que el código se supone que debe hacer, …
    • …una traducción directa del algoritmo obligatorio en GOTO basado en código puede ser mucho más fácil para validar que un lío de la bandera de las variables y abusado de los bucles.

  11. 7

    Me resulta curioso que algunas personas van tan lejos como para dar una lista de casos donde goto es aceptable, diciendo que todos los otros usos son inaceptables. ¿De verdad crees que sabes en cada caso, goto es la mejor opción para expresar un algoritmo?

    Para ilustrar, me voy a dar un ejemplo de que aquí nadie ha demostrado aún:

    Hoy estaba escribiendo código para insertar un elemento en una tabla hash. La tabla hash es una memoria caché de los cálculos previos que se puede sobrescribir en la voluntad (que afectan el rendimiento, pero no la corrección).

    Cada segmento de la tabla hash tiene 4 slots, y tengo un montón de criterios para decidir qué elemento va a sobrescribir cuando el depósito está lleno. Ahora esto significa hacer hasta tres pasa a través de un cubo, como este:

    //Overwrite an element with same hash key if it exists
    for (add_index=0; add_index < ELEMENTS_PER_BUCKET; add_index++)
    if (slot_p[add_index].hash_key == hash_key)
    goto add;
    //Otherwise, find first empty element
    for (add_index=0; add_index < ELEMENTS_PER_BUCKET; add_index++)
    if ((slot_p[add_index].type == TT_ELEMENT_EMPTY)
    goto add;
    //Additional passes go here...
    add:
    //element is written to the hash table here

    Ahora, si yo no uso de goto, ¿qué sería de este código parece?

    Algo como esto:

    //Overwrite an element with same hash key if it exists
    for (add_index=0; add_index < ELEMENTS_PER_BUCKET; add_index++)
    if (slot_p[add_index].hash_key == hash_key)
    break;
    if (add_index >= ELEMENTS_PER_BUCKET) {
    //Otherwise, find first empty element
    for (add_index=0; add_index < ELEMENTS_PER_BUCKET; add_index++)
    if ((slot_p[add_index].type == TT_ELEMENT_EMPTY)
    break;
    if (add_index >= ELEMENTS_PER_BUCKET)
    //Additional passes go here (nested further)...
    }
    //element is written to the hash table here

    Que sería peor y peor si más pases agregado, mientras que la versión con goto mantiene el mismo nivel de sangría en todo momento y evita el uso de espurias si las declaraciones cuyo resultado está implícita en la ejecución del bucle anterior.

    Hay otro caso donde goto hace el código más limpio y más fácil de entender y escribir… estoy seguro de que hay muchos más, así que no pretendo saber todos los casos donde goto es útil, faltarle el respeto a ningún bien que no podía pensar.

    • En el ejemplo que usted dio, prefiero refactorizar que muy significativamente. En general, trato de evitar one-liner comentarios que dicen lo que el siguiente fragmento de código se está haciendo. En lugar de eso, se me rompe que fuera en su propia función que se denomina similar a la del comentario. Si usted fuera a hacer una transformación, entonces esta función sería dar una descripción de alto nivel de lo que la función está haciendo, y cada una de las nuevas funciones que el estado, cómo hacer cada paso. Yo siento que mucho más importante que cualquier oposición a goto está teniendo cada función en el mismo nivel de abstracción. De esta manera se evita goto es un bono.
    • Realmente no has explicado cómo agregar más funciones se libra de la ira, los múltiples niveles de sangría y las falsas declaraciones y si…
    • Sería algo parecido a esto, el uso de contenedor estándar de notación: container::iterator it = slot_p.find(hash_key); if (it != slot_p.end()) it->overwrite(hash_key); else it = slot_p.find_first_empty(); puedo encontrar ese tipo de programación mucho más fácil de leer. Cada función en este caso podría ser escrito como una función pura, que es mucho más fácil a la razón acerca de. La función principal ahora se explica lo que el código no sólo por el nombre de las funciones y, a continuación, si lo desea, puede buscar en sus definiciones, para averiguar cómo se hace.
    • El hecho de que alguien tiene que dar ejemplos, de cómo ciertos algoritmos, naturalmente, debe usar un goto – es una triste reflexión sobre lo poco pensamiento algorítmico en la actualidad!! Por supuesto, @Ricardo ejemplo, es (uno de muchos) ejemplos perfectos de donde goto es elegante y obvia.
  12. 6

    La regla con goto que utilizamos es que goto está bien para saltar hacia adelante a una sola salida de limpieza de punto en una función. En realidad las funciones complejas en las que relajarse, que la regla para permitir que otro salto hacia adelante. En ambos casos estamos evitando profundamente anidada si las declaraciones que se producen a menudo con el código de error de comprobación, que ayuda a mejorar la legibilidad y mantenimiento.

    • Pude ver algo como que el ser útil en un lenguaje como C. sin Embargo, cuando usted tiene el poder de C++ constructores / destructores, que generalmente no es tan útil.
    • » En realidad funciones complejas en las que relajarse, que la regla para permitir que otro salto hacia delante» Sin un ejemplo, que suena como si usted está haciendo las funciones complejas aún más compleja mediante el uso de saltos. No sería la «mejor» enfoque para refactorizar y dividir dichas funciones complejas?
    • Esta fue la última finalidad para la que he utilizado goto. No echo de menos ir en Java, porque tiene try-finally que puede hacer el mismo trabajo.
  13. 5

    El más reflexivo y profundo debate de goto, de sus usos legítimos, y la alternativa de construcciones que se pueden utilizar en lugar de «virtuoso goto», pero puede ser abusado fácilmente como goto, es Donald Knuth en su artículo «Programación estructurada con las Instrucciones goto«, en el diciembre de 1974 Computing Surveys (volumen 6, no. 4. p 261 – 301).

    No es de extrañar que algunos aspectos de este de 39 años de edad, de papel son de fecha: Órdenes de magnitud de los aumentos en la potencia de procesamiento a hacer algunas de Knuth las mejoras de rendimiento imperceptible para el tamaño moderado de los problemas, y los nuevos lenguajes de programación construcciones se han inventado desde entonces. (Por ejemplo, bloques try-catch subsumir Zahn a Construir, a pesar de que rara vez se usa de esa manera.) Pero Knuth cubre todos los lados de la discusión, y debería ser de lectura obligatoria antes de que alguien rehashes el tema.

  14. 3

    En un módulo de Perl, que de vez en cuando desee crear subrutinas o el cierre de la marcha. La cosa es que una vez que has creado la subrutina, ¿cómo se puede llegar a ella. Usted sólo podríamos llamar, pero entonces, si la subrutina utiliza caller() no va a ser tan útil como podría ser. Que es donde el goto &subrutina variación puede ser útil.

    Aquí está un ejemplo rápido:

    sub AUTOLOAD{
    my($self) = @_;
    my $name = $AUTOLOAD;
    $name =~ s/.*:://;
    *{$name} = my($sub) = sub{
    # the body of the closure
    }
    goto $sub;
    # nothing after the goto will ever be executed.
    }

    También puede utilizar este formulario de goto para proporcionar una forma rudimentaria de la cola de llamada optimización.

    sub factorial($){
    my($n,$tally) = (@_,1);
    return $tally if $n <= 1;
    $tally *= $n--;
    @_ = ($n,$tally);
    goto &factorial;
    }

    ( En Perl versión 5 16 que estaría mejor escrito como goto __SUB__; )

    Hay un módulo que se va a importar una cola modificador y uno que se va a importar se repiten si no te gusta usar esta forma de goto.

    use Sub::Call::Tail;
    sub AUTOLOAD {
    ...
    tail &$sub( @_ );
    }
    use Sub::Call::Recur;
    sub factorial($){
    my($n,$tally) = (@_,1);
    return $tally if $n <= 1;
    recur( $n-1, $tally * $n );
    }

    La mayoría de las otras razones para el uso de goto se hace mejor con otras palabras clave.

    Como rehacering un poco de código:

    LABEL: ;
    ...
    goto LABEL if $x;
    {
    ...
    redo if $x;
    }

    O ir a la última de un poco de código desde varios lugares:

    goto LABEL if $x;
    ...
    goto LABEL if $y;
    ...
    LABEL: ;
    {
    last if $x;
    ...
    last if $y
    ...
    }
  15. 2

    Si es así, ¿por qué?

    C no tiene multi-nivel/etiquetado descanso, y no todos los flujos de control fácilmente puede ser modelada con C la iteración y la toma de primitivas. gotos recorrer un largo camino para corregir estas fallas.

    A veces es más claro para el uso de una variable de indicador de algún tipo de efectuar una especie de pseudo-multi-nivel de romper, pero no es siempre superior a la de goto (al menos un goto permite determinar fácilmente el control se va a, a diferencia de una variable de indicador), y a veces simplemente no quieren pagar el desempeño de los precios de banderas/otros contorsiones para evitar el goto.

    libavcodec es un rendimiento sensible a la pieza de código. La expresión directa del flujo de control es probablemente una prioridad, ya que tienden a funcionar mejor.

  16. 2

    Tan bien que nadie se implementó el «PROVIENEN DE la» declaración de….

    • ..excepto en INTERCAL! catb.org/~esr/intercal
    • O en C++, C#, Java, JS, Python, Ruby….etc, etc, etc. Sólo se habla de «excepciones».
  17. 2

    Puedo encontrar el do{} while(false) uso absolutamente repugnante. Es concebible que podría convencerme de que es necesario que en algún extraño caso, pero nunca que es limpio sensible código.

    Si debe hacer algo así en bucle, ¿por qué no hacer que la dependencia de la variable de indicador explícito?

    for (stepfailed=0 ; ! stepfailed ; /*empty*/)
    • No debería /*empty*/ ser stepfailed = 1? En cualquier caso, ¿cómo es esto mejor que un do{}while(0)? En tanto, usted necesita para break fuera de él (o en el tuyo stepfailed = 1; continue;). Parece innecesario para mí.
  18. 2

    1) El uso más común de goto, que yo sepa es emular el manejo de excepciones en idiomas que no lo ofrecen, es decir, en C. (El código dado por Nuclear de arriba es solo que.) Mira el código fuente de Linux y vas a ver un bazillion gotos utilizado de esa manera; había alrededor de 100.000 gotos en el código de Linux de acuerdo a una encuesta rápida realizada en el año 2013: http://blog.regehr.org/archives/894. Goto uso es siquiera mencionado en el Linux guía de estilo: https://www.kernel.org/doc/Documentation/CodingStyle. Como la programación orientada a objetos es emulado mediante estructuras rellena con punteros a función, goto tiene su lugar en la programación de C. Por lo que es de derecho: Dijkstra o Linus (y todos los kernel de Linux codificadores)? Es la teoría vs práctica básicamente.

    Sin embargo, existe la costumbre de gotcha para no tener compilador de soporte de nivel y los controles para el común de las construcciones/patrones: es más fácil su uso incorrecto y de introducir errores sin tiempo de compilación cheques. Windows y Visual C++, pero en C modo de ofrecer a excepción de la manipulación a través de la SEH/VEH por esta misma razón: las excepciones son útiles incluso fuera de la programación orientada a objetos los lenguajes, es decir, en un lenguaje procedimental. Pero el compilador no siempre se puede salvar el pellejo, incluso si se ofrece sintáctica de apoyo para las excepciones en el lenguaje. Considere como ejemplo de este último caso, la famosa Apple SSL «goto fail» error, que acabamos de duplicar un goto, con consecuencias desastrosas (https://www.imperialviolet.org/2014/02/22/applebug.html):

    if (something())
    goto fail;
    goto fail; //copypasta bug
    printf("Never reached\n");
    fail:
    //control jumps here

    Puede tener exactamente el mismo error usando el compilador admite excepciones, por ejemplo, en C++:

    struct Fail {};
    try {
    if (something())
    throw Fail();
    throw Fail(); //copypasta bug
    printf("Never reached\n");
    }
    catch (Fail&) {
    //control jumps here
    }

    Pero ambas variantes del error puede evitarse si el compilador analiza y advierte acerca del código inalcanzable. Por ejemplo compilar con Visual C++ en el /W4 nivel de advertencia encuentra el error en ambos casos. Java, por ejemplo, prohíbe código inalcanzable (donde se puede encontrar!) por una buena razón: es probable que sea un error en el medio de Joe código. Mientras el goto construcción no permite a los objetivos que el compilador no puede fácilmente averiguar, como gotos a la direcciones(**), no es más difícil para que el compilador encuentre inaccesible código dentro de una función con gotos que el uso de Dijkstra-aprobado el código.

    (**) Nota: Gotos a la línea los números son posibles en algunas versiones de Basic, por ejemplo, GOTO 10*x, donde x es una variable. En lugar de crear confusión, en Fortran «calculada goto» se refiere a un constructo que es equivalente a una sentencia switch en C. C Estándar no permite calculada gotos en el lenguaje, pero sólo gotos estáticamente/sintácticamente declarado etiquetas. De C de GNU, sin embargo, tiene una extensión para obtener la dirección de una etiqueta (unario, el prefijo && operador) y también permite un goto a una variable de tipo void*. Ver https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html para más información sobre este oscuro sub-tema. El resto de este post ins no se trate con que oscuros de C de GNU característica.

    Estándar de C (es decir, no calculada) gotos en general no son la razón por la inalcanzable código no puede ser encontrada en tiempo de compilación. La razón habitual es la lógica de código como el siguiente. Dado

    int computation1() {
    return 1;
    }
    int computation2() {
    return computation1();
    }

    Es tan difícil para un compilador para encontrar código inalcanzable en cualquiera de los 3 siguientes construcciones:

    void tough1() {
    if (computation1() != computation2())
    printf("Unreachable\n");
    }
    void tough2() {
    if (computation1() == computation2())
    goto out;
    printf("Unreachable\n");
    out:;
    }
    struct Out{};
    void tough3() {
    try {
    if (computation1() == computation2())
    throw Out();
    printf("Unreachable\n");
    }
    catch (Out&) {
    }
    }

    (Disculpe mi llave relacionados con el estilo de codificación, pero traté de mantener a los ejemplos tan compacto como sea posible.)

    Visual C++ /W4 (incluso con /Ox) no se puede encontrar el código inalcanzable en cualquiera de estos, y como usted probablemente sabe, el problema de encontrar código inalcanzable es indecidible en general. (Si no me creen acerca de que: https://www.cl.cam.ac.uk/teaching/2006/OptComp/slides/lecture02.pdf)

    Como una cuestión relacionada con la C goto puede ser utilizado para emular las excepciones sólo en el interior del cuerpo de una función. El estándar de C biblioteca ofrece una setjmp() y longjmp() par de funciones para la simulación de salidas no locales/excepciones, pero esas tienen algunos inconvenientes serios en comparación con lo que otras lenguas que se ofrecen. El artículo de la Wikipedia http://en.wikipedia.org/wiki/Setjmp.h explica bastante bien este último tema. Esta función par que también funciona en Windows (http://msdn.microsoft.com/en-us/library/yz2ez4as.aspx), pero casi nadie los usa no porque SEH/VEH es superior. Incluso en Unix, creo que setjmp y longjmp se utiliza muy raramente.

    2) yo creo que el segundo más común el uso de goto en C es la aplicación de multi-nivel de romper o multi-nivel, que también es bastante controvertida en el caso de uso. Recordemos que Java no permite goto etiqueta, pero permite romper la etiqueta o continuar la etiqueta. De acuerdo a http://www.oracle.com/technetwork/java/simple-142616.html, esto es en realidad el más común de los casos de uso de gotos en C (90% de ellos dicen), pero en mi experiencia subjetiva, el código del sistema tiende a usar gotos para el control de errores más a menudo. Tal vez en el código científico o donde el OS ofrece el manejo de excepciones (Windows), a continuación, multi-nivel de las salidas de la dominante caso de uso. Realmente no dar detalles como para el contexto de su estudio.

    Editado para añadir: resulta que estos dos patrones de uso que se encuentran en el libro de lenguaje C de Kernighan y Ritchie, alrededor de la página 60 (según la edición). Otra cosa a notar es que tanto los casos de uso implican sólo hacia adelante gotos. Y resulta que MISRA C de la edición de 2012 (a diferencia de la edición de 2004) ahora permite que los gotos, mientras que son sólo hacia adelante queridos.

    • A la derecha. El «elefante en la habitación» es que el kernel de Linux, por amor de dios, como un ejemplo de una crítica de la base de código – se carga con goto. Por supuesto que lo es. Obviamente. El «anti-goto-meme» es sólo una curiosidad desde hace décadas. Por SUPUESTO, hay un número de cosas en la programación (en particular, «estática», de hecho «globales» y, por ejemplo, «elseif») que pueden ser objeto de abuso por los no-profesionales. Así que, si eres chico primo es learnin 2 del programa, que les diga «oh no usar variables globales» y «no utilizar nunca elseif».
    • El goto fail error no tiene nada que ver con goto. El problema es causado por la instrucción if sin llaves después. Cualquier declaración de copia pega dos veces habría causado un problema. Considero que ese tipo de desnudo braceless si ser mucho más perjudicial que el goto.
  19. 2

    Algunos dicen que no hay ninguna razón para que el goto en C++. Algunos dicen que en el 99% de los casos hay alternativas mejores. Esto no es un razonamiento, simplemente irracional impresiones. He aquí un ejemplo sólido donde goto conduce a un buen código, algo así como mejorado do-while:

    int i;
    PROMPT_INSERT_NUMBER:
    std::cout << "insert number: ";
    std::cin >> i;
    if(std::cin.fail()) {
    std::cin.clear();
    std::cin.ignore(1000,'\n');
    goto PROMPT_INSERT_NUMBER;          
    }
    std::cout << "your number is " << i;

    Comparar a ir a libre código:

    int i;
    bool loop;
    do {
    loop = false;
    std::cout << "insert number: ";
    std::cin >> i;
    if(std::cin.fail()) {
    std::cin.clear();
    std::cin.ignore(1000,'\n');
    loop = true;          
    }
    } while(loop);
    std::cout << "your number is " << i;

    Veo estas diferencias:

    • anidada {} bloque es necesario (aunque do {...} while parece más familiar)
    • extra loop variable es necesario, se utiliza en cuatro lugares
    • se toma más tiempo para leer y entender el trabajo con la loop
    • la loop no tienen todos los datos, sólo se controla el flujo de la ejecución, lo que es menos comprensible que la simple etiqueta de

    Hay otro ejemplo

    void sort(int* array, int length) {
    SORT:
    for(int i=0; i<length-1; ++i) if(array[i]>array[i+1]) {
    swap(data[i], data[i+1]);
    goto SORT; //it is very easy to understand this code, right?
    }
    }

    Ahora vamos a deshacernos de los «malos» goto:

    void sort(int* array, int length) {
    bool seemslegit;
    do {
    seemslegit = true;
    for(int i=0; i<length-1; ++i) if(array[i]>array[i+1]) {
    swap(data[i], data[i+1]);
    seemslegit = false;
    }
    } while(!seemslegit);
    }

    Ves es el mismo tipo de uso de goto, que está bien estructurado patrón y no hacia adelante goto como muchos de fomentar la única forma recomendada. Seguramente usted quiere evitar «inteligente» código como este:

    void sort(int* array, int length) {
    for(int i=0; i<length-1; ++i) if(array[i]>array[i+1]) {
    swap(data[i], data[i+1]);
    i = -1; //it works, but WTF on the first glance
    }
    }

    El punto es que goto puede ser fácilmente mal, pero goto en sí no tiene la culpa. Tenga en cuenta que la etiqueta ha ámbito de la función en C++, por lo que no contaminan el ámbito global como en el más puro de la asamblea, en la que la superposición de bucles tienen su lugar y son muy comunes – como en el código siguiente para 8051, donde 7segment de visualización está conectado a P1. El programa de bucles rayo segmento de alrededor de:

    ; P1 states loops
    ; 11111110 <-
    ; 11111101  |
    ; 11111011  |
    ; 11110111  |
    ; 11101111  |
    ; 11011111  |
    ; |_________|
    init_roll_state:
    MOV P1,#11111110b
    ACALL delay
    next_roll_state:
    MOV A,P1
    RL A
    MOV P1,A
    ACALL delay
    JNB P1.5, init_roll_state
    SJMP next_roll_state

    Hay otra ventaja: goto puede servir como llamado de bucles, condiciones y otros flujos:

    if(valid) {
    do { //while(loop)
    //more than one page of code here
    //so it is better to comment the meaning
    //of the corresponding curly bracket
    } while(loop);
    } //if(valid)

    O puede utilizar equivalente ir con sangría, así que usted no necesita comentario, si usted elige el nombre de la etiqueta sabiamente:

    if(!valid) goto NOTVALID;
    LOOPBACK:
    //more than one page of code here
    if(loop) goto LOOPBACK;
    NOTVALID:;
  20. 1

    En Perl, el uso de una etiqueta de «goto» a partir de un bucle – el uso de un «pasado» declaración», que es similar a romper.

    Esto permite un mejor control sobre los bucles anidados.

    La tradicional goto etiqueta es compatible también, pero no estoy seguro de que hay demasiados casos en los que esta es la única manera de lograr lo que desea – subrutinas y bucles debería ser suficiente para la mayoría de los casos.

    • Creo que la única forma de goto que nunca usaría en Perl es goto &subroutine. Que se inicia la subrutina con el actual @_, mientras que la sustitución de la actual subrutina en la pila.
  21. 1

    El problema con ‘goto’ y el argumento más importante de la ‘goto-menos programación movimiento, que si se utiliza con demasiada frecuencia su código, aunque podría comportarse correctamente, se convierte en ilegible, tanto, inapelable, etc. En el 99,99% de los casos ‘goto’ lleva a los espaguetis código. Personalmente, no puedo pensar en ninguna buena razón por la que yo usaría ‘goto’.

    • Diciendo: «no puedo pensar en ninguna razón» en su argumento es, formalmente, en.wikipedia.org/wiki/Argument_from_ignorance, aunque yo prefiero la terminología de «prueba por falta de imaginación».
    • MI OPINIÓN correcta: Es una falacia lógica sólo si es empleada post-hoc. A partir de un lenguaje del diseñador punto de vista puede ser un argumento válido para sopesar los costos de la inclusión de una característica (goto). @cschol de uso es similar: Aunque tal vez no el diseño de un lenguaje de ahora, (s)es, básicamente, la evaluación del diseñador esfuerzo.
    • En mi humilde opinión, tener un lenguaje permitir goto excepto en los contextos donde se iba a llevar variables a la existencia tiende a ser más barato que tratar de apoyar a cada tipo de estructura de control que alguien pueda necesitar. La escritura de código con goto puede no ser tan bonito como el uso de alguna otra estructura, pero ser capaz de escribir dicho código con goto ayudará a evitar los «agujeros en la expresividad»–construcciones para que un lenguaje es incapaz de escribir código eficiente.
    • Me temo que vamos a partir, fundamentalmente, de diferentes escuelas de diseño del lenguaje. Me opongo a las lenguas máximo expresiva en el precio de la comprensibilidad (o corrección). Prefiero tener un restrictiva que la de una permisiva idioma.
    • Tiendo a ser de la filosofía de que es posible escribir código ilegible en cualquier idioma, y que icky código más a menudo se deriva de una lengua es la incapacidad para expresar algo que muy bien, que de su capacidad para expresar mal.
    • ¿Conoces alguna ejemplos desde 1990, donde goto causado problemas reales? Yo no. Una oscura ejemplo, probablemente existe en algún lugar, pero, normalmente, goto está bien. El uso de la misma. Disfrutar de ella. Es eficaz y divertido. De todas las construcciones de programación de probabilidades de ser objeto de abuso, goto es relativamente inofensivo. El bool (también inofensivo) es más probable de ser abusado. No inofensivo (en mi opinión) son los extremos a los que algunos programadores de irán para evitar goto incluso cuando goto es la herramienta adecuada para el trabajo, ya que he oído que algunos sabios tio llamado Dijkstra, supuestamente, una vez que se recomienda en contra.
    • Sí, por supuesto que sí. Esto a menudo hace que el código de por tanto es más difícil de leer y razonar acerca de. Prácticamente cada vez que alguien puestos de código que contiene goto en la revisión del código de sitio, eliminando la goto simplifica el código de la lógica.
    • mientras yo muy a menudo de acuerdo con tus ideas, estoy con Konrad en esto: he estado siguiendo el lenguaje de diseño de más de 40 años de programación en una amplia variedad de idiomas. Estoy 100% detrás de la eliminación de goto – ni siquiera lo ofrecen como una opción (en cualquier lenguaje de alto nivel que C). Sabemos lo suficiente ahora para que nunca lo necesita. Generalmente se reemplaza por la prueba de una bandera. (En cualquiera del resto de los «agujeros», el factor de un método, llamada desde varios lugares como sea necesario, y dependen del compilador optimizador en línea que el código de nuevo. O añadir un bool o enumeración de los parámetros de un método existente.)
    • Si nunca lo necesita para ninguna de las cosas que que se necesita hacer, genial. ¿Qué te hace pensar que usted sabe acerca de todo lo que los demás tiene que hacer?
    • Tal vez sería posible para un lenguaje de incluir suficientes estructuras de control para evitar la necesidad de arbitrario goto o de otra manera-innecesaria-banderas, pero yo todavía no he visto ninguna que hacer.

  22. 1

    El GOTO puede ser utilizado, por supuesto, pero hay una cosa más importante que el estilo de código, o si el código es o no es legible que usted debe tener en mente cuando se utiliza: el código en el interior puede no ser tan fuerte como crees.

    Por ejemplo, ver en los dos siguientes fragmentos de código:

    If A <> 0 Then A = 0 EndIf
    Write("Value of A:" + A)

    Un código equivalente con GOTO

    If A == 0 Then GOTO FINAL EndIf
    A = 0
    FINAL:
    Write("Value of A:" + A)

    Lo primero que pensamos es que el resultado de ambos bits de código será que «el Valor de a: 0» (suponemos una ejecución sin paralelismo, por supuesto)

    Que no es correcto: en el primer ejemplo, Una siempre va a ser 0, pero en la segunda muestra (con la instrucción GOTO) a no ser 0. Por qué?

    La razón es porque desde otro punto del programa puedo insertar un GOTO FINAL sin controlar el valor de A.

    Este ejemplo es muy obvio, pero como programas de conseguir más complicado, la dificultad de ver ese tipo de cosas aumenta.

    Relacionados con el material puede ser encontrado en el famoso artículo de el Señor de Dijkstra «Un caso en contra de la declaración»

    • Esta era a menudo el caso en la vieja escuela BÁSICA. En variantes modernas, sin embargo, no está permitido saltar en el centro de otra función…o, en muchos casos, incluso más allá de la declaración de una variable. Básicamente, (juego de palabras no es la intención), lenguas modernas han hecho que el «salvaje», GOTOs que Dijkstra estaba hablando…y la única forma de utilizar ya que estaba argumentando en contra, es cometer ciertos otros atroces pecados. 🙂
  23. 1

    Puedo usar goto, en el siguiente caso:
    cuando sea necesario para el regreso de funcions en diferentes lugares, y antes de devolver algunas de desinicialización que se necesita hacer:

    no goto versión:

    int doSomething (struct my_complicated_stuff *ctx)    
    {
    db_conn *conn;
    RSA *key;
    char *temp_data;
    conn = db_connect();  
    if (ctx->smth->needs_alloc) {
    temp_data=malloc(ctx->some_size);
    if (!temp_data) {
    db_disconnect(conn);
    return -1;      
    }
    }
    ...
    if (!ctx->smth->needs_to_be_processed) {
    free(temp_data);    
    db_disconnect(conn);    
    return -2;
    }
    pthread_mutex_lock(ctx->mutex);
    if (ctx->some_other_thing->error) {
    pthread_mutex_unlock(ctx->mutex);
    free(temp_data);
    db_disconnect(conn);        
    return -3;  
    }
    ...
    key=rsa_load_key(....);
    ...
    if (ctx->something_else->error) {
    rsa_free(key); 
    pthread_mutex_unlock(ctx->mutex);
    free(temp_data);
    db_disconnect(conn);       
    return -4;  
    }
    if (ctx->something_else->additional_check) {
    rsa_free(key); 
    pthread_mutex_unlock(ctx->mutex);
    free(temp_data);
    db_disconnect(conn);       
    return -5;  
    }
    pthread_mutex_unlock(ctx->mutex);
    free(temp_data);    
    db_disconnect(conn);    
    return 0;     
    }

    goto versión:

    int doSomething_goto (struct my_complicated_stuff *ctx)
    {
    int ret=0;
    db_conn *conn;
    RSA *key;
    char *temp_data;
    conn = db_connect();  
    if (ctx->smth->needs_alloc) {
    temp_data=malloc(ctx->some_size);
    if (!temp_data) {
    ret=-1;
    goto exit_db;   
    }
    }
    ...
    if (!ctx->smth->needs_to_be_processed) {
    ret=-2;
    goto exit_freetmp;      
    }
    pthread_mutex_lock(ctx->mutex);
    if (ctx->some_other_thing->error) {
    ret=-3;
    goto exit;  
    }
    ...
    key=rsa_load_key(....);
    ...
    if (ctx->something_else->error) {
    ret=-4;
    goto exit_freekey; 
    }
    if (ctx->something_else->additional_check) {
    ret=-5;
    goto exit_freekey;  
    }
    exit_freekey:
    rsa_free(key);
    exit:    
    pthread_mutex_unlock(ctx->mutex);
    exit_freetmp:
    free(temp_data);        
    exit_db:
    db_disconnect(conn);    
    return ret;     
    }

    La segunda versión hace que sea más fácil, cuando necesita cambiar algo en la cancelación de las declaraciones (se utiliza cada vez en el código), y reduce la probabilidad de pasar por alto ninguna de ellas, cuando la adición de una nueva sucursal. Movimiento en una función no ayuda aquí, debido a que la cancelación se puede hacer en diferentes «niveles».

    • Esta es la razón por la que hemos finally bloques en C#
    • ^ como @JohnSaunders dijo. Este es un ejemplo de «uso de goto porque una lengua carece del adecuado control de la construcción». Sin EMBARGO es un código olor a requerir MÚLTIPLES goto puntos cerca de la devolución. No es un estilo de programación que es más seguro y más fácil para el tornillo de seguridad) Y no requiere gotos, que funciona bien incluso en idiomas sin «finalmente»: diseño de la «limpieza» de las llamadas por lo que son inofensivas, no que la limpieza es necesaria. Factor de todo, pero la limpieza en un método, que utiliza el múltiple de retorno de diseño. Llamar a ese método, a continuación, hacer la limpieza de las llamadas.
    • Tenga en cuenta que el enfoque que describen requiere un nivel adicional de la llamada al método (pero sólo en un idioma que carece de finally). Como alternativa, puede utilizar gotos, pero a un común punto de salida, que siempre hace todos de la limpieza. Pero cada limpieza método cualquiera puede manejar un valor es nulo o ya limpio, o está protegido por una prueba condicional, por lo que omite cuando no es apropiado.
    • este no es un código de olor; de hecho, es extremadamente un patrón común en C y es considerado uno de los más válidos para el uso de goto. Quieres crear 5 métodos, cada uno con su propio innecesario si de la prueba, sólo para controlar la limpieza de esta función? Ahora que ha creado el código Y el rendimiento de la hinchazón. O usted podría utilizar goto.
    • 1) «crear 5 métodos» – No. Estoy sugiriendo un solo método que limpia todos los recursos que tienen un valor no nulo. O ver a mi alternativa, que utiliza gotos que todo se vaya a la de la misma punto de salida, que tiene la misma lógica (lo que requiere un extra si por recurso, como usted dice). Pero no importa, cuando el uso de C que se haga sea cual sea la razón por la que el código está en C, y su casi seguro que un trade-off que favorece a los más «directa» de código. (Mi sugerencia maneja situaciones complejas donde ningún recurso puede o no puede haber sido asignado. Pero sí, la exageración, en este caso).
    • En cualquier idioma que es el nivel superior de C, me gustaría hacerlo de la manera que me sugieren, por una razón sencilla: varios gotos requiere cualquier programador de mantener el código (seguimiento de un oscuro bug o hacer cambios), para examinar cuidadosamente el gotos para asegurarse de que cada uno vaya a donde deben. En este caso, asegurándose de que estén en el orden correcto. Esto contrasta con el hecho de tener un solo punto de salida, que las pruebas de cada recurso para no nulo, y se limpia de los que están allí. Su mucho más fácil de «inspección» para observar que todo está limpio. Si bien esto es cierto en C, es más aceptable.

  24. 0

    Que viene muy bien para el personaje sabio de la cadena de procesamiento de vez en cuando.

    Imaginar algo como esto printf-esque ejemplo:

    for cur_char, next_char in sliding_window(input_string) {
    if cur_char == '%' {
    if next_char == '%' {
    cur_char_index += 1
    goto handle_literal
    }
    # Some additional logic
    if chars_should_be_handled_literally() {
    goto handle_literal
    }
    # Handle the format
    }
    # some other control characters
    else {
    handle_literal:
    # Complicated logic here
    # Maybe it's writing to an array for some OpenGL calls later or something,
    # all while modifying a bunch of local variables declared outside the loop
    }
    }

    Podría refactorizar que goto handle_literal a una llamada a una función, pero si es la modificación de varias variables locales, usted tendría que pasar referencias a cada uno a menos que su lenguaje soporta mutable cierres. Usted todavía tiene que usar un continue declaración (que es sin duda una forma de goto) después de la llamada para obtener la misma semántica si su lógica hace que un caso más no de trabajo.

    También he utilizado gotos juiciosamente en lexers, generalmente para casos similares. Usted no necesita la mayoría del tiempo, pero está bueno tener de esos extraños casos.

Dejar respuesta

Please enter your comment!
Please enter your name here