나는 흥미 롭다. 따라서 조 사용 고글을 착용 할 시간이며 컴파일러 또는 컴파일 플래그에 액세스 할 수 없으므로 독창적이어야합니다. 또한이 코드에 대한 의미가 없기 때문에 모든 가정에 대해 나쁜 생각은 아닙니다.
먼저 실제 유형을 확인합시다 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 경연 대회 밖에서 그런 종류의 코드를 작성해서는 안됩니다. 컴파일러에서 허용하는 경우 경고 플래그를 더 추가하고 해당 구문이있는 코드베이스를 수정하려는 경우 경고를 오류로 설정하십시오.