131

I've found this C program from the web:

#include <stdio.h>

int main(){

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

    return 0;
}

The interesting thing with this program is that when it is compiled and run in C89 mode, it prints C89 and when it is compiled and run in C99 mode, it prints C99. But I am not able to figure out how this program works.

Can you explain how the second argument of printf works in the above program?

11
  • 48
    Hint: the C++-style // comment was introduced in C99.
    – Paul R
    Commented Jun 29, 2015 at 12:17
  • 4
    Nice trick – but it fails with gcc. Without std=c99 you'll get a warning, and if you ignore it, gcc will still interpret the // as start of a comment (ah – you have to use -pedantic as well. I have that on by default.)
    – Jongware
    Commented Jun 29, 2015 at 12:20
  • 3
    @Jongware Well, I got C89 with explicit std=c89 in gcc 4.9.2.
    – ikh
    Commented Jun 29, 2015 at 12:24
  • 63
    Just in case someone finds this while searching for a way to test for C99 support; please use something like #if __STDC_VERSION__ >= 199901L, not the // comment trick. =)
    – Arkku
    Commented Jun 29, 2015 at 12:30
  • 10
    It also prints "C99" for C11...
    – Lundin
    Commented Jun 29, 2015 at 12:55

3 Answers 3

135

C99 allows //-style comments, C89 does not. So, to translate:

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

the line comment // is introduced since C99. Therefore your code is equal to this 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 */

and equal to this 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

Because // comments only exist in C99 and later standards, the code is equivalent to the following:

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

Correct code would be:

#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;
}
4
  • off-by-one error in your answer, how do you get 90 when it's supposed to print 89?
    – Pimgd
    Commented Jun 29, 2015 at 13:18
  • 1
    @Pimgd C89 and C90 is the same thing. stackoverflow.com/questions/17206568/…
    – Lundin
    Commented Jun 29, 2015 at 13:45
  • 3
    They mean the same thing but it's not the same string. Standing by my original question.
    – Pimgd
    Commented Jun 30, 2015 at 7:41
  • @Pimgd The purpose of the above code is not to sate some artificial task to print strings after a given format. The purpose is to demonstrate how real-word applications outside the IOCCC prints which C version the program was compiled with. C90 is more correct to use than "C89" or "ANSI-C".
    – Lundin
    Commented Jun 30, 2015 at 9:23

Not the answer you're looking for? Browse other questions tagged or ask your own question.