Ejemplos de buenos gotos en C o C++ [cerrado]

Resuelto fizzer asked hace 15 años • 16 respuestas

En este hilo, analizamos ejemplos de buenos usos de gotoen C o C++. Está inspirado en una respuesta. que la gente votó porque pensaba que estaba bromeando.

Resumen (la etiqueta cambió de la original para que la intención sea aún más clara):

infinite_loop:

    // code goes here

goto infinite_loop;

Por qué es mejor que las alternativas:

  • Es específico. gotoes la construcción del lenguaje que causa una rama incondicional. Las alternativas dependen del uso de estructuras que soporten ramas condicionales, con una condición degenerada de siempre verdadera.
  • La etiqueta documenta la intención sin comentarios adicionales.
  • El lector no tiene que escanear el código intermedio en busca de los primeros breaks (aunque todavía es posible que un hacker sin principios simule continuecon un temprano goto).

Normas:

  • Finge que los gotófobos no ganaron. Se entiende que lo anterior no se puede utilizar en código real porque va en contra del lenguaje establecido.
  • Supongamos que todos hemos oído hablar de "Goto considerado dañino" y sabemos que goto se puede utilizar para escribir código espagueti.
  • Si no está de acuerdo con un ejemplo, critíquelo únicamente por sus méritos técnicos ("Porque a la gente no le gusta goto" no es una razón técnica).

A ver si podemos hablar de esto como mayores.

Editar

Esta pregunta parece terminada ahora. Generó algunas respuestas de alta calidad. Gracias a todos, especialmente a aquellos que tomaron en serio mi ejemplo del pequeño bucle. La mayoría de los escépticos estaban preocupados por la falta de alcance del bloque. Como señaló @quinmars en un comentario, siempre puedes colocar tirantes alrededor del cuerpo del bucle. Tomo nota de eso for(;;)y while(true)tampoco te doy las llaves gratis (y omitirlas puede causar errores molestos). De todos modos, no desperdiciaré más tu capacidad cerebral en esta nimiedad: puedo vivir con lo inofensivo, idiomático for(;;)ywhile(true) (mejor si quiero conservar mi trabajo).

Teniendo en cuenta las otras respuestas, veo que mucha gente lo ve gotocomo algo que siempre hay que reescribir de otra manera. Por supuesto, puede evitarlo gotointroduciendo un bucle, una bandera adicional, una pila de mensajes anidados ifo lo que sea, pero ¿por qué no considerar si gotoes quizás la mejor herramienta para el trabajo? Dicho de otra manera, ¿cuánta fealdad están dispuestas a soportar las personas para evitar utilizar una característica incorporada del lenguaje para el propósito previsto? Mi opinión es que incluso añadir una bandera es un precio demasiado alto a pagar. Me gusta que mis variables representen cosas en los dominios del problema o de la solución. 'Únicamente para evitar un goto' no es suficiente.

Aceptaré la primera respuesta que dio el patrón C para bifurcarse a un bloque de limpieza. En mi opinión, este es el caso más sólido a favor gotode todas las respuestas publicadas, ciertamente si lo mides por las contorsiones que debe realizar un enemigo para evitarlo.

fizzer avatar Oct 29 '08 10:10 fizzer
Aceptado

Aquí hay un truco que he oído que usa la gente. Aunque nunca lo he visto en estado salvaje. Y sólo se aplica a C porque C++ tiene RAII para hacer esto de manera más idiomática.

void foo()
{
    if (!doA())
        goto exit;
    if (!doB())
        goto cleanupA;
    if (!doC())
        goto cleanupB;

    /* everything has succeeded */
    return;

cleanupB:
    undoB();
cleanupA:
    undoA();
exit:
    return;
}
Greg Rogers avatar Oct 29 '2008 04:10 Greg Rogers

La necesidad clásica de GOTO en C es la siguiente

for ...
  for ...
    if(breakout_condition) 
      goto final;

final:

No existe una forma sencilla de salir de los bucles anidados sin un goto.

Paul Nathan avatar Oct 29 '2008 04:10 Paul Nathan