¿Por qué estoy viendo tantas construcciones (;;)? [cerrado]

14

A mi modo de pensar, un bucle for se utiliza para iterar sobre un rango conocido o determinable.

String[] names = //something;
for ( int i = 0; i < names.length; i++ ) { //do stuff }

que es equivalente (alcance de i aparte) a:

String[] names = //something;
int i = 0;
while (i < names.length )
{
   // do stuff
   i++;
}

En otras palabras, el forbucle es simplemente un azúcar sintáctico (muy útil) para una whileconstrucción comúnmente utilizada .

Sin embargo, veo muchas for(;;)construcciones en la web que son funcionalmente equivalentes awhile(true)

¿Cuál es el razonamiento para esto? ¿Por qué se preferiría el bucle infinito for sobre el bucle infinito while?

// ¡Incluso vi un libro de texto de Java que no usaba bucles while! Conduciendo a construcciones tan monstruosas como:

String input = getInput();
for( ; !inputIsValid(input) ; )
{
   //redo;
}
Chris Cudmore
fuente
La razón principal es la preferencia. La legibilidad debería entrar en juego al hacer la elección, sin embargo, YMMV.
Aaron McIver
¿Por qué alguien preferiría la construcción incómoda?
Chris Cudmore
10
Podrías intercambiar whiley foraquí y la pregunta no cambiaría. while(true)y for(;;)significa lo mismo. Obviamente tiene una fuerte preferencia por while, otros pueden tener una preferencia igualmente fuerte por for. Es imposible decir que uno es más correcto que el otro.
Caleb
3
@ Chris, no me parece for(;;)confuso en absoluto. Es un lenguaje C estándar, uno que documentará en la sección 3.5 de K&R (2e). Yo entiendo que usted no me gusta; se debe entender que otros prefieren obviamente ella (lo contrario nunca lo vería). Puede ser más o menos aceptable en lenguajes distintos de C; ha etiquetado este lenguaje independiente que solo disminuye la posibilidad de una respuesta definitiva. Nuevamente, voté para cerrar porque la Q no es constructiva; si me hubiera ofendido, habría marcado como ofensivo en lugar de o además del cierre. Eso es todo.
Caleb
1
Personalmente, creo que hay una oportunidad real aquí para tener otra sintaxis completamente para bucles infinitos: algo así comowheeeeeeee { ... }
detly

Respuestas:

33

Es una retención de las viejas prácticas de programación en el PDP-11 (sí, dije viejo ). Solía ​​guardar una sola instrucción, que era útil para hacer que los bucles se ejecuten más rápido.

Consulte lo siguiente para obtener información adicional: http://www.flounder.com/exceptions.htm

Edward Robertson
fuente
3
Eso es precisamente lo que estaba buscando. Hay una razón real y legítima, pero ya no es válida.
Chris Cudmore
1
@chris Nnnope, los compiladores modernos a veces se quejan de usar una constante en la condición de un bucle. No es puramente un remanente.
Izkata
Hay algo mas que eso. Recuerdo haber escrito C a principios de la década de 1990 en sistemas Unix y, si bien (verdadero) {} no era una opción. No había un tipo booleano estándar, pero varios sistemas unix definieron los suyos en los archivos de encabezado C. De memoria, al menos un proveedor de Unix definió VERDADERO como cero supuestamente para ayudar a procesar los retornos de funciones, ya que la convención era devolver cero en caso de éxito, y los números positivos eran fallas. Esto significaba que mientras (VERDADERO) {} no era portátil.
Michael Shaw
1
No puedo encontrarlo en este momento, pero podría jurar que hace unos años Dennis Ritchie escribió una publicación en Usenet afirmando que esto era simplemente incorrecto, y él / ellos usan la for(;;)sintaxis como (en su opinión) una declaración más directa de intención de que no se establecieran criterios para salir del bucle.
Jerry Coffin
@Ptolomeo: Bueno, ciertamente podrías haber escrito while(1) { }.
Ed S.
10

algunos compiladores darán una advertencia (algo así como la expresión condicional es constante ) cuando se usa while( 1 )pero for( ; ; )no hay nada de qué advertir. Los programadores quieren código sin advertencias, por lo que usan la variante for.

stijn
fuente
Sin embargo, algunas cosas sobre las que advierten los compiladores son perfectamente válidas e incluso (en algunos casos especiales) inevitables. Entonces, algunos de nosotros tratamos las advertencias como, bueno, advertencias. Si los ignora, por supuesto, puede sumergirse en las malditas cosas y no ver las importantes, pero hay pragmas y opciones para desactivar las advertencias, local o globalmente. Básicamente, sí, es mejor no tener advertencias, pero generalmente necesito una razón más fuerte que esa para adoptar un estilo de código peor. Aquí no es peor solo diferente, pero de todos modos los bucles "infinitos" son raros (o muy mal estilo).
Steve314
5

Es un hábito adquirido de la programación en C donde no hay un tipo booleano. Mientras que (1) sería el equivalente potencialmente, pero For (;;) se usa a menudo como se muestra en K&R si no recuerdo mal. Sospecho que también había una razón de hardware en alguna parte.

Ingeniero mundial
fuente
44
... sospechar que era una razón de hardware ...
Aaron McIver
2
Como mencionó Edward Robertson, la razón es porque el compilador de C en el PDP-11 no se dio cuenta de que lo verdadero en "while (verdadero)" era una constante de tiempo de compilación y agregaría una instrucción adicional (una comparación) al generar el ensamblaje. Debido a los recursos limitados disponibles en el PDP-11, los programadores usaron el bucle for para optimizar esa instrucción adicional fuera del programa.
Jetti
3

porque (;;) puede leerse como "para siempre", lo que algunos consideran más natural que "mientras sea verdadero".

Oskar N.
fuente
Si bien esta no es la razón original, es una razón secundaria por la cual la preferencia se mantuvo mucho después de que la razón original se volviera obsoleta. Sin embargo, es muy difícil sacar evidencia para respaldar esto, aparte de preguntar a programadores experimentados.
DarenW
-2

Todos los programadores experimentados que he pedido pueden reconocer for(;;)más rápido que while(true)o while(1).

Kevin Cline
fuente
2
Cualquier programador que valga la pena debería poder reconocer los tres al instante. Los tres son lo suficientemente comunes como para que cualquiera que haya pasado más de 5 minutos leyendo códigos haya visto cada uno de ellos muchas veces.
cHao
1
Los estudios han demostrado que los programadores experimentados pueden comprender for(;;)14 ms más rápido que while(1):-)
kevin cline