Мене заінтригує Отже, час надіти захисні окуляри, і оскільки я не маю доступу до компілятора чи прапорів компіляції, мені потрібно отримати винахідливий характер. Крім того, що нічого з цього коду не має сенсу, це не є поганою ідеєю питання кожного припущення.
Спочатку давайте перевіримо фактичний тип gets
. У мене є невелика хитрість для цього:
template <class> struct Name;
int main() {
Name<decltype(gets)> n;
// keep this function call here
cout << FirstFactorial(gets(stdin));
return 0;
}
І це виглядає ... нормально:
/tmp/613814454/Main.cpp:16:19: warning: 'gets' is deprecated [-Wdeprecated-declarations]
Name<decltype(gets)> n;
^
/usr/include/stdio.h:638:37: note: 'gets' has been explicitly marked deprecated here
extern char *gets (char *__s) __wur __attribute_deprecated__;
^
/usr/include/x86_64-linux-gnu/sys/cdefs.h:254:51: note: expanded from macro '__attribute_deprecated__'
# define __attribute_deprecated__ __attribute__ ((__deprecated__))
^
/tmp/613814454/Main.cpp:16:26: error: implicit instantiation of undefined template 'Name<char *(char *)>'
Name<decltype(gets)> n;
^
/tmp/613814454/Main.cpp:12:25: note: template is declared here
template <class> struct Name;
^
1 warning and 1 error generated.
gets
позначено як застаріле і має підпис char *(char *)
. Але як тоді FirstFactorial(gets(stdin));
складати?
Спробуємо ще щось:
int main() {
Name<decltype(gets(stdin))> n;
// keep this function call here
cout << FirstFactorial(gets(stdin));
return 0;
}
Що дає нам:
/tmp/286775780/Main.cpp:15:21: error: implicit instantiation of undefined template 'Name<int>'
Name<decltype(8)> n;
^
Нарешті , ми отримуємо що - то: decltype(8)
. Тож ціле gets(stdin)
було текстово замінено на введення ( 8
).
І речі стають більш дивними. Помилка компілятора триває:
/tmp/596773533/Main.cpp:18:26: error: no matching function for call to 'gets'
cout << FirstFactorial(gets(stdin));
^~~~
/usr/include/stdio.h:638:14: note: candidate function not viable: no known conversion from 'struct _IO_FILE *' to 'char *' for 1st argument
extern char *gets (char *__s) __wur __attribute_deprecated__;
Отже, ми отримуємо очікувану помилку для cout << FirstFactorial(gets(stdin));
Я перевірив макрос, і оскільки, #undef gets
здається, нічого не робить, схоже, що це не макрос.
Але
std::integral_constant<int, gets(stdin)> n;
Він компілює.
Але
std::integral_constant<int, gets(stdin)> n; // OK
std::integral_constant<int, gets(stdin)> n2; // ERROR wtf??
Не з очікуваною помилкою у n2
рядку.
І знову ж таки, майже будь-яка модифікація main
змушує лінію cout << FirstFactorial(gets(stdin));
виплюнути очікувану помилку.
Більше того, stdin
насправді начебто пусте.
Тож я можу лише зробити висновок і припустити, що у них є невелика програма, яка аналізує джерело і намагається (погано) замінити gets(stdin)
вхідне значення тестового випадку, перш ніж фактично подавати його в компілятор. Якщо хтось має кращу теорію або насправді знає, що вони роблять, будь ласка, поділіться!
Це, очевидно, дуже погана практика. Досліджуючи це, я виявив, що тут є принаймні питання ( приклад ) про це, і тому, що люди не мають уявлення про те, що там є сайт, який робить це, їх відповідь - "не використовуй gets
використання ... замість", що справді хороша порада, але лише більше плутає ОП, оскільки будь-яка спроба дійсного читання з stdin на цьому сайті буде невдалою.
TLDR
gets(stdin)
недійсний C ++. Цей твір використовує цей трюк (з яких причин я не можу з’ясувати). Якщо ви хочете продовжувати надсилати на сайті (я ні його не схвалюю, ні не схвалюю), ви повинні використовувати цю конструкцію, яка в іншому випадку не мала б сенсу, але пам’ятайте, що вона крихка. Практично будь-які модифікації main
виплюнуть помилку. Поза межами цього сайту використовуйте звичайні методи зчитування вводу.
stdin
в стандартній бібліотеці є aFILE*
, а вказівник на будь-який тип перетворюється наchar*
, який є типом аргументуgets()
. Однак ви ніколи і ніколи ніколи не повинні писати такий код поза закритим конкурсом C. Якщо ваш компілятор навіть приймає це, додайте більше попереджувальних прапорів, і якщо ви намагаєтеся виправити базу коду, яка містить цю конструкцію, перетворіть попередження в помилки.