Wie gibt das folgende Programm "C89" aus, wenn es im C89-Modus kompiliert wird, und "C99", wenn es im C99-Modus kompiliert wird?

128

Ich habe dieses C-Programm aus dem Internet gefunden:

#include <stdio.h>

int main(){

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

    return 0;
}

Das Interessante an diesem Programm ist, dass es beim Kompilieren und Ausführen im C89-Modus gedruckt wird C89und beim Kompilieren und Ausführen im C99-Modus gedruckt wird C99. Aber ich kann nicht herausfinden, wie dieses Programm funktioniert.

Können Sie erklären, wie das zweite Argument von printfim obigen Programm funktioniert?

Spikatrix
quelle
47
Hinweis: Der //Kommentar im C ++ - Stil wurde in C99 eingeführt.
Paul R
4
Schöner Trick - aber es scheitert mit gcc. Ohne dass std=c99Sie eine Warnung erhalten, und wenn Sie sie ignorieren, gccwird dies immer noch// als Beginn eines Kommentars interpretiert (ah - Sie müssen es auch verwenden -pedantic. Ich habe das standardmäßig aktiviert.)
usr2564301
3
@ Jongware Nun, ich habe C89mit explizit std=c89in gcc 4.9.2.
Ikh
60
Nur für den Fall, dass jemand dies findet, während er nach einer Möglichkeit sucht, die C99-Unterstützung zu testen. Bitte benutze so etwas wie #if __STDC_VERSION__ >= 199901L, nicht den //Kommentar-Trick. =)
Arkku
10
Es druckt auch "C99" für C11 ...
Lundin

Antworten:

133

C99 erlaubt //Kommentare im Stil, C89 nicht. Also, um zu übersetzen:

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
quelle
25

Der Zeilenkommentar //wird seit C99 eingeführt. Daher ist Ihr Code in C89 gleich

#include <stdio.h>

int main(){

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

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

und gleich in 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
quelle
9

Da //Kommentare nur in C99 und späteren Standards vorhanden sind, entspricht der Code den folgenden Angaben:

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

Richtiger Code wäre:

#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
quelle
Off-by-One-Fehler in Ihrer Antwort, wie erhalten Sie 90, wenn es 89 drucken soll?
Pimgd
1
@Pimgd C89 und C90 ist das gleiche. stackoverflow.com/questions/17206568/…
Lundin
3
Sie bedeuten dasselbe, aber es ist nicht dieselbe Zeichenfolge. Zu meiner ursprünglichen Frage stehen.
Pimgd
@Pimgd Der Zweck des obigen Codes besteht nicht darin, eine künstliche Aufgabe zum Drucken von Zeichenfolgen nach einem bestimmten Format zu erfüllen. Der Zweck ist zu demonstrieren, wie Real-Word-Anwendungen außerhalb des IOCCC drucken, mit welcher C-Version das Programm kompiliert wurde. C90 ist korrekter als "C89" oder "ANSI-C".
Lundin