Як виводиться програма "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у вищевказаній програмі?


47
Підказка: //коментар у стилі C ++ був представлений у C99.
Пол Р

4
Хороший трюк - але він не вдається gcc. Без цього std=c99ви отримаєте попередження, і якщо ви проігноруєте це, gccвсе одно буде інтерпретувати //як початок коментаря (ах - ви повинні також використовувати -pedantic. У мене це за замовчуванням.)
usr2564301

3
@Jongware Ну, я отримав C89з явним std=c89в gcc 4.9.2.
ikh

60
Про всяк випадок, коли хтось виявить це під час пошуку способу перевірити підтримку C99; будь ласка, використовуйте щось на кшталт #if __STDC_VERSION__ >= 199901L, а не //трюк з коментарями. =)
Арку

10
Він також друкує "C99" для C11 ...
Лундін

Відповіді:


133

C99 дозволяє використовувати //коментарі у стилі, 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*/

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?
Пімгд

1
@Pimgd C89 і C90 - це одне і те ж. stackoverflow.com/questions/17206568/…
Лундін

3
Вони означають одне і те ж, але це не та сама строка. Стоячи моїм оригінальним запитанням.
Пімгд

@Pimgd Метою вищевказаного коду є не наситити якесь штучне завдання надрукувати рядки після заданого формату. Мета - продемонструвати, як додатки в реальному слові за межами IOCCC друкують, з якою версією C була складена програма. C90 правильніше використовувати, ніж "C89" або "ANSI-C".
Лундін
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.