Comment le programme ci-dessous produit-il `C89` lorsqu'il est compilé en mode C89 et` C99` lorsqu'il est compilé en mode C99?

128

J'ai trouvé ce programme C sur le Web:

#include <stdio.h>

int main(){

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

    return 0;
}

La chose intéressante avec ce programme est que lorsqu'il est compilé et exécuté en mode C89, il imprime C89et lorsqu'il est compilé et exécuté en mode C99, il imprime C99. Mais je ne suis pas en mesure de comprendre comment ce programme fonctionne.

Pouvez-vous expliquer comment le deuxième argument de printffonctionne dans le programme ci-dessus?

Spikatrix
la source
47
Astuce: le //commentaire de style C ++ a été introduit dans C99.
Paul R
4
Belle astuce - mais elle échoue avec gcc. Sans std=c99vous un avertissement, et si vous l' ignorez, gccvous toujours interpréter le //comme début d'un commentaire (ah - vous devez utiliser -pedantic. De plus, j'ai que par défaut.)
usr2564301
3
@Jongware Eh bien, j'ai obtenu C89avec explicite std=c89dans gcc 4.9.2.
ikh
60
Juste au cas où quelqu'un trouverait cela en cherchant un moyen de tester le support C99; veuillez utiliser quelque chose comme #if __STDC_VERSION__ >= 199901L, pas l' //astuce des commentaires. =)
Arkku
10
Il imprime également "C99" pour C11 ...
Lundin

Réponses:

133

C99 autorise les //commentaires de style -style, C89 ne le fait pas. Donc, pour traduire:

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
la source
25

le commentaire de ligne //est introduit depuis C99. Par conséquent, votre code est égal à cela dans C89

#include <stdio.h>

int main(){

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

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

et égal à cela 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
la source
9

Étant donné que les //commentaires n'existent que dans les normes C99 et ultérieures, le code est équivalent à ce qui suit:

#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;
}

Le code correct serait:

#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
la source
erreur par erreur dans votre réponse, comment obtenez-vous 90 alors qu'il est censé imprimer 89?
Pimgd
1
@Pimgd C89 et C90, c'est la même chose. stackoverflow.com/questions/17206568/…
Lundin
3
Ils signifient la même chose mais ce n'est pas la même chaîne. Je réponds à ma question initiale.
Pimgd
@Pimgd Le but du code ci-dessus n'est pas de remplir une tâche artificielle pour imprimer des chaînes après un format donné. Le but est de montrer comment les applications de mots réels en dehors de l' IOCCC impriment la version C avec laquelle le programme a été compilé. C90 est plus correct à utiliser que "C89" ou "ANSI-C".
Lundin