Ejemplos de buenos gotos en C o C++ [cerrado]
En este hilo, analizamos ejemplos de buenos usos de goto
en 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.
goto
es 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
break
s (aunque todavía es posible que un hacker sin principios simulecontinue
con un tempranogoto
).
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 goto
como algo que siempre hay que reescribir de otra manera. Por supuesto, puede evitarlo goto
introduciendo un bucle, una bandera adicional, una pila de mensajes anidados if
o lo que sea, pero ¿por qué no considerar si goto
es 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 goto
de todas las respuestas publicadas, ciertamente si lo mides por las contorsiones que debe realizar un enemigo para evitarlo.
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;
}
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.