Как программа ниже выводит C89 при компиляции в режиме C89 и C99 при компиляции в режиме C99?

128

Я нашел эту программу C в сети:

#include <stdio.h>

int main(){

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

    return 0;
}

В этой программе интересно то, что когда она компилируется и запускается в режиме C89, она печатает, C89а когда она компилируется и запускается в режиме C99, она печатает C99. Но я не могу понять, как работает эта программа.

Вы можете объяснить, как работает второй аргумент printfв указанной выше программе?

Spikatrix
источник
47
Подсказка: //комментарий в стиле C ++ появился в C99.
Paul R
4
Хороший трюк - но с ним не справиться gcc. Без std=c99предупреждения вы получите предупреждение, а если проигнорируете его, gccвсе равно будет интерпретироваться //как начало комментария (ах, вы тоже должны использовать -pedantic. У меня это
включено
3
@Jongware Ну, я получил C89с явным std=c89в gcc 4.9.2.
ikh
60
На всякий случай, если кто-то обнаружит это при поиске способа проверить поддержку C99; пожалуйста, используйте что-то вроде #if __STDC_VERSION__ >= 199901L, а не //трюк с комментариями. =)
Arkku
10
Он также печатает "C99" для C11 ...
Lundin

Ответы:

133

C99 разрешает //комментарии в стиле -style, C89 - нет. Итак, чтобы перевести:

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

комментарий к строке //введен с C99. Поэтому ваш код равен этому в C89

#include <stdio.h>

int main(){

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

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

и равно этому в 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
источник
9

Поскольку //комментарии существуют только в стандартах C99 и более поздних версиях, код эквивалентен следующему:

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

Правильный код будет:

#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;
}
Лундин
источник
пошаговая ошибка в вашем ответе, как вы получаете 90, когда предполагается, что напечатано 89?
Pimgd
1
@Pimgd C89 и C90 - это одно и то же. stackoverflow.com/questions/17206568/…
Lundin
3
Они означают одно и то же, но это не одна и та же строка. По моему первоначальному вопросу.
Pimgd
@Pimgd Целью приведенного выше кода не является выполнение какой-то искусственной задачи по печати строк после заданного формата. Цель состоит в том, чтобы продемонстрировать, как приложения реального времени за пределами IOCCC выводят, с какой версией C была скомпилирована программа. C90 более правильно использовать, чем «C89» или «ANSI-C».
Lundin