Tôi tò mò. Vì vậy, thời gian để đặt kính điều tra và vì tôi không có quyền truy cập vào trình biên dịch hoặc cờ biên dịch, tôi cần có được sáng tạo. Ngoài ra bởi vì không có gì về mã này có nghĩa là nó không phải là một câu hỏi ý tưởng tồi mỗi giả định.
Trước tiên hãy kiểm tra loại thực tế gets
. Tôi có một mẹo nhỏ cho việc đó:
template <class> struct Name;
int main() {
Name<decltype(gets)> n;
// keep this function call here
cout << FirstFactorial(gets(stdin));
return 0;
}
Và điều đó có vẻ ... bình thường:
/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
được đánh dấu là không dùng nữa và có chữ ký char *(char *)
. Nhưng sau đó là FirstFactorial(gets(stdin));
biên dịch như thế nào ?
Hãy thử một cái gì đó khác:
int main() {
Name<decltype(gets(stdin))> n;
// keep this function call here
cout << FirstFactorial(gets(stdin));
return 0;
}
Cung cấp cho chúng tôi:
/tmp/286775780/Main.cpp:15:21: error: implicit instantiation of undefined template 'Name<int>'
Name<decltype(8)> n;
^
Cuối cùng, chúng tôi nhận được một cái gì đó : decltype(8)
. Vì vậy, toàn bộ gets(stdin)
đã được thay thế bằng văn bản với đầu vào ( 8
).
Và những điều nhận được weirder. Lỗi trình biên dịch tiếp tục:
/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__;
Vì vậy, bây giờ chúng tôi nhận được lỗi dự kiến cho cout << FirstFactorial(gets(stdin));
Tôi đã kiểm tra một macro và vì #undef gets
dường như không làm gì cả, có vẻ như nó không phải là một macro.
Nhưng
std::integral_constant<int, gets(stdin)> n;
Nó biên dịch.
Nhưng
std::integral_constant<int, gets(stdin)> n; // OK
std::integral_constant<int, gets(stdin)> n2; // ERROR wtf??
Không có lỗi dự kiến tại n2
dòng.
Và một lần nữa, gần như bất kỳ sửa đổi nào để main
làm cho dòng cout << FirstFactorial(gets(stdin));
phát sinh lỗi dự kiến.
Hơn nữa, stdin
thực tế dường như là trống rỗng.
Vì vậy, tôi chỉ có thể kết luận và suy đoán rằng họ có một chương trình nhỏ phân tích nguồn và cố gắng (kém) để thay thế gets(stdin)
bằng giá trị đầu vào của trường hợp thử nghiệm trước khi thực sự đưa nó vào trình biên dịch. Nếu bất cứ ai có một lý thuyết tốt hơn hoặc thực sự biết những gì họ đang làm xin vui lòng chia sẻ!
Đây rõ ràng là một thực tế rất xấu. Trong khi nghiên cứu điều này, tôi thấy có ít nhất một câu hỏi ở đây ( ví dụ ) về điều này và bởi vì mọi người không biết rằng có một trang web ngoài đó, câu trả lời của họ là "không sử gets
dụng ... thay vào đó" thực sự là một lời khuyên tốt nhưng chỉ khiến OP bối rối hơn vì mọi nỗ lực đọc hợp lệ từ stdin sẽ thất bại trên trang web này.
TLD
gets(stdin)
C ++ không hợp lệ. Đây là một mánh lới quảng cáo mà trang web cụ thể này sử dụng (vì lý do tôi không thể tìm ra). Nếu bạn muốn tiếp tục gửi trên trang web (tôi không xác nhận nó cũng không xác nhận nó), bạn phải sử dụng cấu trúc này nếu không sẽ không có ý nghĩa gì, nhưng hãy lưu ý rằng nó dễ vỡ. Hầu như bất kỳ sửa đổi nào main
sẽ gây ra lỗi. Bên ngoài trang web này sử dụng phương pháp đọc đầu vào bình thường.
stdin
trong thư viện chuẩn là mộtFILE*
và một con trỏ tới bất kỳ loại nào chuyển đổi thànhchar*
, đó là loại đối số củagets()
. Tuy nhiên, bạn không bao giờ nên viết loại mã đó bên ngoài một cuộc thi C khó hiểu. Nếu trình biên dịch của bạn thậm chí chấp nhận nó, hãy thêm nhiều cờ cảnh báo và nếu bạn đang cố sửa một cơ sở mã có cấu trúc đó, hãy biến cảnh báo thành lỗi.