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?

200_success
  • 7,286
  • 1
  • 43
  • 74
Spikatrix
  • 20,225
  • 7
  • 37
  • 83
  • 48
    Hint: the C++-style `//` comment was introduced in C99. – Paul R Jun 29 '15 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 Jun 29 '15 at 12:20
  • 3
    @Jongware Well, I got `C89` with explicit `std=c89` in gcc 4.9.2. – ikh Jun 29 '15 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 Jun 29 '15 at 12:30
  • 10
    It also prints "C99" for C11... – Lundin Jun 29 '15 at 12:55
  • @Arkku Never knew that before. Thanks! – Spikatrix Jun 29 '15 at 12:59
  • @CoolGuy Correct way to obtain C version posted below. – Lundin Jun 29 '15 at 13:09
  • @Lundin Yeah saw it. I also googled `__STDC_VERSION__` and found [this](http://stackoverflow.com/a/9294314/3049655) and [this](http://clc-wiki.net/wiki/STDC_VERSION) very helpful – Spikatrix Jun 29 '15 at 13:12
  • 1
    Related: http://stackoverflow.com/questions/2038200/write-a-program-that-will-print-c-if-compiled-as-an-ansi-c-program-and-c – jamesdlin Jul 01 '15 at 08:28
  • Is `printf()` integer argument cast redundant `(int)` ? – EsmaeelE Feb 02 '20 at 23:29
  • 1
    @EsmaeelE No, it is required as the result of the operation is a `double` but the `%d` format specifier expects an `int`. – Spikatrix Feb 03 '20 at 09:38

3 Answers3

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 */
Ismael Miguel
  • 4,185
  • 1
  • 31
  • 42
Paul Rubel
  • 26,632
  • 7
  • 60
  • 80
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*/
ikh
  • 10,119
  • 1
  • 31
  • 70
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;
}
Lundin
  • 195,001
  • 40
  • 254
  • 396
  • off-by-one error in your answer, how do you get 90 when it's supposed to print 89? – Pimgd Jun 29 '15 at 13:18
  • 1
    @Pimgd C89 and C90 is the same thing. http://stackoverflow.com/questions/17206568/what-is-the-difference-between-c-c99-ansi-c-and-gnu-c-a-general-confusion-reg/17209532#17209532 – Lundin Jun 29 '15 at 13:45
  • 3
    They mean the same thing but it's not the same string. Standing by my original question. – Pimgd Jun 30 '15 at 07: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](http://www.ioccc.org/) prints which C version the program was compiled with. C90 is more correct to use than "C89" or "ANSI-C". – Lundin Jun 30 '15 at 09:23