In che modo il programma seguente genera `C89` quando compilato in modalità C89 e` C99` quando compilato in modalità C99?


128

Ho trovato questo programma C dal web:

#include <stdio.h>

int main(){

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

    return 0;
}

La cosa interessante di questo programma è che quando viene compilato ed eseguito in modalità C89, stampa C89e quando viene compilato ed eseguito in modalità C99, stampa C99. Ma non sono in grado di capire come funziona questo programma.

Puoi spiegare come funziona il secondo argomento del printfprogramma sopra?


47
Suggerimento: il //commento in stile C ++ è stato introdotto in C99.
Paul R,

4
Bel trucco, ma fallisce gcc. Senza std=c99si otterrà un messaggio di avviso, e se si ignora, gccsarà ancora interpretare il //come inizio di un commento (ah - si deve utilizzare -pedantic. Così ho che per impostazione predefinita.)
usr2564301

3
@Jongware Bene, ho ottenuto C89esplicito std=c89in gcc 4.9.2.
ikh

60
Nel caso in cui qualcuno lo trovi durante la ricerca di un modo per testare il supporto C99; si prega di utilizzare qualcosa di simile #if __STDC_VERSION__ >= 199901L, non il //trucco dei commenti. =)
Arkku,

10
Stampa anche "C99" per C11 ...
Lundin,

Risposte:


133

C99 consente //commenti in stile, C89 no. Quindi, per tradurre:

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 */

25

il commento alla riga //viene introdotto dal C99. Pertanto il tuo codice è uguale a questo in 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 uguale a questo 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*/

9

Poiché i //commenti esistono solo negli standard C99 e successivi, il codice è equivalente al seguente:

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

Il codice corretto sarebbe:

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

off-by-one errore nella risposta, come si ottengono 90 quando si suppone che stampi 89?
Pimgd,

1
@Pimgd C89 e C90 è la stessa cosa. stackoverflow.com/questions/17206568/…
Lundin

3
Significano la stessa cosa ma non è la stessa stringa. In attesa della mia domanda originale.
Pimgd,

@Pimgd Lo scopo di questo codice non è quello di saziare alcune attività artificiali per stampare stringhe dopo un determinato formato. Lo scopo è dimostrare come le applicazioni con parole reali al di fuori di IOCCC stampano la versione C con cui è stato compilato il programma. C90 è più corretto da utilizzare rispetto a "C89" o "ANSI-C".
Lundin,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.