¿Necesita ayuda para entender esto para el código de bucle en C

Considere el siguiente código en C:

void main() { int a=0; for(printf("\nA"); a; printf("\nB")); printf("\nC"); printf("\nD"); } 

Cuando lo compilo utilizando la versión 3.0 de Turb C ++ y gcc-4.3.4, obtengo lo siguiente como la salida en AMBOS casos:

 A C D 

Sin embargo, si compilo el siguiente código:

 void main() { for(printf("\nA"); 0; printf("\nB")); printf("\nC"); printf("\nD"); } 

La salida de gcc-4.3.4 es la misma que en el caso anterior, pero turbo c ++ 3.0 produce la siguiente salida:

 A B C D 

En primer lugar, no tengo idea de lo que está pasando aquí! Además, ¿por qué la salida del comstackdor gcc es la misma para ambos códigos pero en el caso del comstackdor turboc ++ 3.0, la salida es diferente? ¿Puede alguien arrojar algo de luz?

EDITAR:

De hecho, a alguien se le hizo esta pregunta en una entrevista para una compañía de TI y cuando no dio la respuesta, el entrevistador dio esta explicación. Pero esto me parece estúpido. ¿Cómo puede pedirle a alguien que use un “error” como si fuera un “servicio” provisto por el idioma? Para que se le llame “facilidad” y “técnica”, ya sea que pasemos 0 como literal en la segunda expresión o una variable cuyo valor sea 0, el resultado debería haber sido el mismo.

¿Me equivoco al concluir que el entrevistador fue muy tonto al hacer una pregunta como esa y que muestra su incompetencia?

La salida de TCC para el segundo ejemplo es incorrecta.

De la norma C99:

La statement

para ( cláusula-1 ; expresión-2 ; expresión-3 ) statement

se comporta de la siguiente manera: La expresión expresión-2 es la expresión de control que se evalúa antes de cada ejecución del cuerpo del bucle. La expresión expresión-3 se evalúa como una expresión vacía después de cada ejecución del cuerpo del bucle. […]

Obviamente, aquí no hay iteraciones, por lo que la expresión-3 nunca debe ejecutarse.

De manera similar, en el estándar C90 (o al menos en un borrador que encontré ), dice:

Excepto por el comportamiento de una instrucción de continuación en el cuerpo del bucle, la instrucción

  for ( expression-1 ; expression-2 ; expression-3 ) statement 

y la secuencia de afirmaciones

  expression-1 ; while ( expression-2) { statement expression-3 ; } 

son equivalentes

Turbo C ++ 3.0 fue lanzado en la década de 1990, y fue seguido muy rápidamente con un lanzamiento de 3.1.

Supongo que su antiguo comstackdor tenía una serie de errores, que se actualizaron rápidamente. Además, es posible que no haya tenido tales errores, pero puede haber emitido un ensamblaje optimizado que falla bajo las nuevas architectures de revestimiento de tuberías.

En cualquier caso, se garantiza que Turbo C ++ 3.0 no es compatible con su plataforma actual. Cuando se trata de un comstackdor que no es compatible porque la plataforma se creó casi 20 años después, realmente no puede culparlo por emitir el progtwig incorrecto.

La salida de gcc es correcta.

La salida de Turbo C ++ 3.0 en el primer caso es correcta.

La salida de TurboC ++ 3.0 en el segundo caso es incorrecta.

Parece que has encontrado un caso de borde, lo que lleva a una generación de código incorrecta, en el comstackdor Turbo C ++ 3.0.

A for-stmt en C o C ++ tiene la syntax general

para (inicialización; prueba; reinicialización) stmt

Las inicializaciones se realizan una vez, antes de que comience el bucle. La prueba se realiza en la parte superior del bucle. Si la prueba es verdadera, se realiza el stmt, y luego las reinicializaciones y el bucle se repite.

En su caso, printf (“\ nA”) es la inicialización, a (o 0) es la prueba, printf (“\ nB”) es la reinicialización, y el stmt está vacío.

Deberías haber visto la A (y lo hiciste). La prueba debería haber fallado en el primer paso, lo que significa que nunca debería haber visto el stmt (pero no lo sabe), y nunca debería haber visto el B. Aquí es donde Turbo C ++ 3.0 cagó en la segunda prueba.

¿Cuál es la syntax completa del bucle “para” en C (y otras en caso de que sean compatibles)?

Esta pregunta cita la parte aplicable de la norma. La tercera expresión no debe evaluarse a menos que el bucle se ejecute al menos una vez. Por lo tanto, diría que en el segundo caso, el comstackdor anterior está equivocado al imprimir ‘B’.

la semántica de for es que la primera expresión se evalúa (inicializador), luego la segunda expresión se evalúa (terminator) y luego, si el terminador se evalúa a cero, se ejecuta el cuerpo de for, luego se evalúa la tercera expresión (avance) y Volver a evaluar el terminador.

Como no tienes cuerpo, esa parte equivale a ninguna expresión evaluada. Sobre esta base, el bucle debe ejecutarse de la siguiente manera:

 printf("\nA"); a; // yields 0 -> terminate loop 

Esto es precisamente lo que sucede.

En su segundo ejemplo, debería suceder lo mismo (como en el caso de gcc ) ya que 0 se evalúa como 0.

Es posible que el turbo C ++ , al ver la constante 0, haya intentado realizar algún tipo de optimización de desenrollado de bucle (y no lo haya hecho correctamente)