İlgilendim. Bu yüzden, araştırma gözlüklerini takma zamanı ve derleyici veya derleme bayraklarına erişimim olmadığından yaratıcı olmalıyım. Ayrıca, bu kodla ilgili hiçbir şey mantıklı olmadığından, her varsayım kötü bir fikir sorusu değildir.
Önce gerçek türünü kontrol edelim gets
. Bunun için küçük bir numara var:
template <class> struct Name;
int main() {
Name<decltype(gets)> n;
// keep this function call here
cout << FirstFactorial(gets(stdin));
return 0;
}
Ve bu görünüyor ... normal:
/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
onaylanmadı olarak işaretlendi ve imzası var char *(char *)
. Ama sonra nasıl FirstFactorial(gets(stdin));
derleniyoruz?
Başka bir şey deneyelim:
int main() {
Name<decltype(gets(stdin))> n;
// keep this function call here
cout << FirstFactorial(gets(stdin));
return 0;
}
Hangi bize verir:
/tmp/286775780/Main.cpp:15:21: error: implicit instantiation of undefined template 'Name<int>'
Name<decltype(8)> n;
^
Nihayet biz bir şey alıyorsanız: decltype(8)
. Böylece tüm gets(stdin)
metinsel olarak input ( 8
) ile değiştirildi .
Ve işler tuhaflaşıyor. Derleyici hatası devam ediyor:
/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__;
Şimdi beklenen hatayı alıyoruz cout << FirstFactorial(gets(stdin));
Bir makroyu kontrol ettim ve #undef gets
hiçbir şey yapmıyor gibi göründüğü için makro değil.
Fakat
std::integral_constant<int, gets(stdin)> n;
Derler.
Fakat
std::integral_constant<int, gets(stdin)> n; // OK
std::integral_constant<int, gets(stdin)> n2; // ERROR wtf??
n2
Satırda beklenen hata ile yok .
Ve yine, main
hattın yapılması için hemen hemen tüm değişiklikler cout << FirstFactorial(gets(stdin));
beklenen hatayı tükürür.
Üstelik stdin
aslında boş görünüyor.
Bu yüzden sadece kaynağı ayrıştıran ve değiştirmeye çalışan (zayıf) küçük bir programları olduğu sonucuna varabilirim. gets(stdin)
derleyen ve gerçekten derleyiciye beslemeden önce test durumu giriş değeri ile . Eğer herhangi biri daha iyi bir teoriye sahipse ya da ne yaptığını gerçekten biliyorsa lütfen paylaşın!
Açıkçası bu çok kötü bir uygulamadır. Bunu araştırırken burada en azından bir soru olduğunu buldum ( örnek ) olduğunu ve insanların bunu yapan bir site olduğunu bilmedikleri için, cevapları "kullanımı gets
kullanma ... yerine" kullanmayın. iyi bir tavsiye ancak OP'yi daha fazla karıştırır, çünkü stdin'den geçerli bir okuma girişimi bu sitede başarısız olacaktır.
TLDR
gets(stdin)
geçersiz C ++. Bu sitenin kullandığı bir hile (hangi nedenlerle anlayamıyorum). Sitede göndermeye devam etmek istiyorsanız (ne onaylamıyorum ne de onaylamıyorum) aksi takdirde mantıklı olmayan, ancak kırılgan olduğunun farkında olan bu yapıyı kullanmanız gerekir. Hemen hemen tüm değişiklikler main
bir hata verecektir. Bu sitenin dışında normal giriş okuma yöntemleri kullanın.
stdin
standart kitaplığı bir olduğunuFILE*
ve herhangi bir tip dönüştürür bir işaretçichar*
argümanı türüdür,gets()
. Ancak, bu tür bir kodu asla gizli bir C yarışmasının dışında yazmamalısınız. Derleyiciniz bile kabul ederse, daha fazla uyarı bayrağı ekleyin ve içinde bu yapıya sahip bir kod tabanını düzeltmeye çalışıyorsanız, uyarıları hatalara dönüştürün.