W jaki sposób poniższy program wyświetla „C89” po skompilowaniu w trybie C89 i „C99” po skompilowaniu w trybie C99?

128

Znalazłem ten program w C z sieci:

#include <stdio.h>

int main(){

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

    return 0;
}

Interesującą rzeczą w przypadku tego programu jest to, że gdy jest kompilowany i uruchamiany w trybie C89, drukuje, C89a kiedy jest kompilowany i uruchamiany w trybie C99, drukuje C99. Ale nie jestem w stanie dowiedzieć się, jak działa ten program.

Czy możesz wyjaśnić, jak działa drugi argument printfw powyższym programie?

Spikatrix
źródło
47
Wskazówka: //komentarz w stylu C ++ został wprowadzony w C99.
Paul R
4
Niezła sztuczka - ale zawodzi gcc. Bez std=c99dostaniesz ostrzeżenie, a jeśli je zignorujesz, nadalgcc będzie interpretować jako początek komentarza (ah - musisz też użyć . Domyślnie mam to włączone).//-pedantic
Jongware
3
@Jongware Cóż, dostałem C89z jawnym std=c89w gcc 4.9.2.
ikh
60
Na wypadek, gdyby ktoś znalazł to podczas szukania sposobu na przetestowanie obsługi C99; użyj czegoś w stylu #if __STDC_VERSION__ >= 199901L, a nie //sztuczki z komentarzem. =)
Arkku
10
Drukuje również "C99" dla C11 ...
Lundin

Odpowiedzi:

133

C99 pozwala na //komentarze w stylu, C89 nie. A więc do przetłumaczenia:

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
źródło
25

komentarz linii //jest wprowadzany od C99. Dlatego twój kod jest równy temu w C89

#include <stdio.h>

int main(){

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

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

i równe temu w 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
źródło
9

Ponieważ //komentarze istnieją tylko w standardach C99 i nowszych, kod jest równoważny z następującym:

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

Poprawny kod to:

#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
źródło
błąd od jednego do drugiego w twojej odpowiedzi, w jaki sposób otrzymujesz 90, skoro ma wydrukować 89?
Pimgd
1
@Pimgd C89 i C90 to to samo. stackoverflow.com/questions/17206568/…
Lundin
3
Mają na myśli to samo, ale to nie jest ten sam ciąg. Stojąc przy moim pierwotnym pytaniu.
Pimgd
@Pimgd Celem powyższego kodu nie jest zaspokojenie jakiegoś sztucznego zadania drukowania ciągów znaków po zadanym formacie. Celem jest zademonstrowanie, w jaki sposób aplikacje typu real-word poza IOCCC wypisują, z której wersji C program został skompilowany. C90 jest bardziej poprawne w użyciu niż „C89” lub „ANSI-C”.
Lundin