興味をそそられます。ですから、調査用のゴーグルを付ける時間です。コンパイラやコンパイルフラグにアクセスできないので、独創性を身につける必要があります。また、このコードについては何も意味がないので、すべての仮定について悪い考えではありません。
まず、実際のタイプを確認しましょう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からの有効な読み取りの試みは失敗するため、OPをさらに混乱させるだけです。
TLDR
gets(stdin)
無効なC ++です。これは、この特定のサイトで使用されている仕掛けです(理由がわからないため)。サイトへの提出を継続したい場合(私はそれを支持することも、支持することもしない)、この構文を使用する必要があります。これは、他の方法では意味がありませんが、壊れやすいことに注意してください。ほとんどすべての変更main
はエラーを吐き出します。このサイト以外では、通常の入力読み取り方法を使用してください。
stdin
標準ライブラリではFILE*
であり、任意の型へのポインタchar*
はの引数の型であるに変換されることに注意してくださいgets()
。ただし、そのようなコードを難読化されたCコンテスト以外で書くことは決してありません。コンパイラがそれを受け入れる場合でも、警告フラグを追加します。その構成が含まれているコードベースを修正しようとしている場合は、警告をエラーに変換します。