2011-03-10 10 views
10

Cuando puedo compilar código C++ con Visual C++ 9 con "nivel de advertencia 4" lo siguiente:¿Cuál es el punto de emitir una advertencia de compilación para "while (true)" y no emitir una para "for (;;)"?

while(true) { 
    //loop body with break on certain condition 
} 

y los siguientes:

for(; true;) { 
    //same loop body 
} 

tanto gatillo C4127: conditional expression is constant advertencia, pero el siguiente:

for(; ;) { 
    //same loop body 
} 

compila sin previo aviso.

¿Por qué esta diferencia, especialmente entre la segunda y la tercera variante?

+1

porque no hay ninguna expresión condicional en el tercer enunciado ... mientras está allí en el segundo y tercer ... ¿cómo puede el compilador generar una advertencia con respecto a la expresión condicional sin tener ninguna? –

+1

Normalmente termino deshabilitando C4127 con '#pragma warning', especialmente cuando uso boost. –

+0

Relacionado: http://stackoverflow.com/questions/224421/constant-value-in-conditional-expression – CesarB

Respuesta

6

La razón es simple, aunque estúpida.

Es importante diagnosticar bucle infinito, pero tal vez no sea evidente:

while(i >= 0) { --i; } // infinite if i unsigned 

while(SOME_MACRO(i)) // err, depends on the expansion of macros 

Es una gran característica de un compilador para producir una advertencia para una prueba tautológica, es una prueba que resulta ser siempre verdadero o siempre falso, porque no es obvio cuando proviene de una macro expansión o dentro de un contexto dependiente.

Parece que VC++ ha llegado demasiado lejos y, en lugar de considerar las condiciones tautológicas, advierte de todas las condiciones true o false que puede encontrar, incluso cuando ya están claramente indicadas en el código.

4

El for (;;) constructo es la forma canónica a intencionalmente código un bucle "sin fin". Me imagino que los diseñadores de compiladores no querían generar una advertencia para eso.

+6

Diría que la causalidad es al revés: es canónica * porque * no emite una advertencia sobre un cierto popular serie de compiladores. –

+0

No creo que sea canónico si incluye compiladores que no sean VS. No creo que gcc advierta sobre esto? –

+0

@jk: En realidad tienes razón, GCC no advierte sobre ninguno de estos constructos. No probé esto, solo especulé. – DevSolar

10

El motivo de advertir al usuario de expresiones condicionales constantes es ayudar a evitar errores donde la expresión termina siendo constante (por ejemplo, debido a un error tipográfico). En el último caso, no hay expresión, por lo que no hay riesgo de que sea accidentalmente constante.

4

No hay punto. Después de todo, la especificación dice langauge ($ 6.5.3/2),

, o ambas, de la condición y la expresión se puede omitir. A condición faltante implica la cláusula implícita mientras que la cláusula es equivalente a mientras que (verdadero).

Así for (; ;) es equivalente a while(true) incluso de acuerdo con la Norma. Por lo tanto, no veo ninguna razón por la cual el compilador debería dar una advertencia en un caso pero no en el otro.

-

Si el compilador decide dar la advertencia, a continuación, en mi opinión, el compilador debe dar aviso cuando la condición es falta a diferencia de cuando está presente, por lo que la advertencia se interpretaría como sugerencia para que el programador mencione su intención claramente y explícitamente.

quiero decir, es for (;;)más probable que sea un error tipográfico que el explícita mención de la condición en la for (;true;). Este último le dice a la intención clara y explícita del programador. Como Steve dice en el comentario:

Para un valor int y, char x = y es equivalente a char x = (char) y, pero es posible que desee una advertencia para una implícita conversión de restricción de el primero, pero no el segundo.

¡Así que la intención explícita no debería recibir una advertencia, mientras que la intención implícita debería recibirla!

+0

@Downvoter: ¿Por qué downvote? – Nawaz

+2

No es mi voto negativo, pero creo que la equivalencia es una pista falsa. Para otro ejemplo, de acuerdo con el estándar 'if (x = y)' es equivalente a 'if ((x = y))', pero GCC advierte sobre el primero y no el segundo. Para un valor int y, 'char x = y' es equivalente a' char x = (char) y', pero es posible que desee una advertencia para una conversión de estrechamiento implícito en el primero pero no en el segundo. –

+2

verdadero, pero encuentro la idea de que aunque (verdadero) es probable que sea un error tipográfico no convincente. imho VS es demasiado quisquilloso aquí –

1

La advertencia del compilador está aquí para ayudar a detectar posibles errores. Usar una condición siempre true en un bucle while es probablemente un error. Para exemple, en el siguiente código, esto es probablemente un error, y me gustaría que el compilador para avisarme de ello:

unsigned int x; 
// ... 
while (x >= 0) { 
    // ... 
} 

En tal situación, en la construcción optimizado el compilador probablemente deducir que la condición siempre es verdadero (ya que un entero sin signo no puede ser menor que 0). Por lo tanto, existe la necesidad de detectar una condición siempre true en el lazo while. Creo que quien escribió la detección de dicho error no tuvo un caso especial, el caso while (true), ya que hay una forma simple de hacer un ciclo infinito con for (;;).

Usted puede leer here, cómo la decisión de añadir una advertencia o no en Visual Studio, se toma (la exemple están a punto C# pero supongo que el equipo tiene la misma regla de oro para la advertencia en C++).

Cuestiones relacionadas