Como o programa abaixo gera `C89` quando compilado no modo C89 e` C99` quando compilado no modo C99?


128

Encontrei este programa C na Web:

#include <stdio.h>

int main(){

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

    return 0;
}

O interessante deste programa é que, quando é compilado e executado no modo C89, ele é impresso C89e quando é compilado e executado no modo C99, é impresso C99. Mas não sou capaz de descobrir como esse programa funciona.

Você pode explicar como o segundo argumento printffunciona no programa acima?


47
Dica: o //comentário no estilo C ++ foi introduzido no C99.
Paul R

4
Bom truque - mas falha com gcc. Sem std=c99você receberá um aviso, e se você ignorá-lo, gccvai ainda interpretar a //como início de comentário (ah - você tem que usar -pedantic. Bem eu tenho que por padrão.)
usr2564301

3
@Ongware Bem, eu fiquei C89com explícito std=c89no gcc 4.9.2.
Ikh

60
Caso alguém encontre isso enquanto procura uma maneira de testar o suporte ao C99; use algo como #if __STDC_VERSION__ >= 199901L, não o //truque de comentários. =)
Arkku

10
Ele também imprime "C99" para C11 ...
Lundin

Respostas:


133

C99 permite //comentários no estilo, C89 não. Então, para traduzir:

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

o comentário da linha //é introduzido desde C99. Portanto, seu código é igual a isso em 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 isso em 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

Como os //comentários existem apenas nos padrões C99 e posteriores, o código é equivalente ao seguinte:

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

O código correto seria:

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

erro um por um na sua resposta, como você obtém 90 quando deveria imprimir 89?
Pimgd

1
@Pimgd C89 e C90 é a mesma coisa. stackoverflow.com/questions/17206568/…
Lundin

3
Eles significam a mesma coisa, mas não é a mesma string. Permanente pela minha pergunta original.
Pimgd

@Pimgd O objetivo do código acima não é saciar alguma tarefa artificial para imprimir seqüências de caracteres após um determinado formato. O objetivo é demonstrar como aplicativos de palavras reais fora da IOCCC imprimem com qual versão C o programa foi compilado. C90 é mais correto de usar que "C89" ou "ANSI-C".
Lundin
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.