¿Cómo sale el siguiente programa `C89` cuando se compila en modo C89 y` C99` cuando se compila en modo C99?

128

He encontrado este programa C de la web:

#include <stdio.h>

int main(){

    printf("C%d\n",(int)(90-(-4.5//**/
    -4.5)));

    return 0;
}

Lo interesante de este programa es que cuando se compila y ejecuta en modo C89, imprime C89y cuando se compila y ejecuta en modo C99, imprime C99. Pero no puedo entender cómo funciona este programa.

¿Puedes explicar cómo funciona el segundo argumento de printfen el programa anterior?

Spikatrix
fuente
47
Sugerencia: el //comentario de estilo C ++ se introdujo en C99.
Paul R
44
Buen truco, pero falla gcc. Sin std=c99obtendrá una advertencia, y si usted lo ignora, gccse sigue interpretar el //como comienzo de un comentario (ah - se han de utilizar -pedantic., Así que tengo que de forma predeterminada.)
usr2564301
3
@Jongware Bueno, tengo C89explícito std=c89en gcc 4.9.2.
ikh
6060
En caso de que alguien encuentre esto mientras busca una forma de probar el soporte C99; usa algo como #if __STDC_VERSION__ >= 199901L, no el //truco del comentario. =)
Arkku
10
También imprime "C99" para C11 ...
Lundin

Respuestas:

133

C99 permite //comentarios de estilo, C89 no. Entonces, para traducir:

C99:

 printf("C%d\n",(int)(90-(-4.5     /*Some  comment stuff*/
                         -4.5)));
// Outputs: 99

C89:

printf("C%d\n",(int)(90-(-4.5/      
                         -4.5)));
/* so  we get 90-1 or 89 */
Paul Rubel
fuente
25

El comentario de línea //se introduce desde C99. Por lo tanto, su código es igual a esto en C89

#include <stdio.h>

int main(){

    printf("C%d\n",(int)(90-(-4.5/
-4.5)));

    return 0;
}
/* 90 - (-4.5 / -4.5) = 89 */

e igual a esto en C99

#include <stdio.h>

int main(){

    printf("C%d\n",(int)(90-(-4.5
-4.5)));

    return 0;
}
/* 90 - (-4.5 - 4.5) = 99*/
ikh
fuente
9

Como los //comentarios solo existen en los estándares C99 y posteriores, el código es equivalente al siguiente:

#include <stdio.h>

int main (void)
{
  int vers;

  #if   __STDC_VERSION__ >= 201112L
    vers = 99; // oops
  #elif __STDC_VERSION__ >= 199901L
    vers = 99;
  #else
    vers = 90;
  #endif

  printf("C%d", vers);

  return 0;
}

El código correcto sería:

#include <stdio.h>

int main (void)
{
  int vers;

  #if   __STDC_VERSION__ >= 201112L
    vers = 11;
  #elif __STDC_VERSION__ >= 199901L
    vers = 99;
  #else
    vers = 90;
  #endif

  printf("C%d", vers);

  return 0;
}
Lundin
fuente
error uno por uno en su respuesta, ¿cómo obtiene 90 cuando se supone que imprime 89?
Pimgd
1
@Pimgd C89 y C90 es lo mismo. stackoverflow.com/questions/17206568/…
Lundin
3
Significan lo mismo pero no es la misma cadena. De pie junto a mi pregunta original.
Pimgd
@Pimgd El propósito del código anterior no es guardar alguna tarea artificial para imprimir cadenas después de un formato dado. El propósito es demostrar cómo las aplicaciones de palabras reales fuera de IOCCC imprimen con qué versión C se compiló el programa. C90 es más correcto de usar que "C89" o "ANSI-C".
Lundin