【发布时间】:2019-08-11 15:33:13
【问题描述】:
Coderbyte 是一个在线编码挑战网站(我是在 2 分钟前发现的)。
The first C++ challenge 你有一个需要修改的 C++ 框架:
#include <iostream> #include <string> using namespace std; int FirstFactorial(int num) { // Code goes here return num; } int main() { // Keep this function call here cout << FirstFactorial(gets(stdin)); return 0; }
如果你对 C++ 不太熟悉,那么首先出现在你眼中的*是:
int FirstFactorial(int num);
cout << FirstFactorial(gets(stdin));
所以,好的,代码调用 gets 自 C++11 以来已弃用,自 C++14 以来已被删除,这本身就是不好的。
但后来我意识到:gets 的类型是 char*(char*)。所以它不应该接受 FILE* 参数并且结果不应该可以用来代替 int 参数,但是......它不仅编译时没有任何警告或错误,而且它运行并实际上传递了将输入值更正为FirstFactorial。
在这个特定站点之外,代码无法编译(如预期的那样),那么这里发生了什么?
*实际上第一个是using namespace std,但这与我的问题无关。
【问题讨论】:
-
注意标准库中的
stdin是FILE*,指向任意类型的指针都转换为char*,也就是gets()的参数类型。但是,您永远不应该在混淆的 C 竞赛之外编写这种代码。如果您的编译器甚至接受它,请添加更多警告标志,如果您尝试修复包含该构造的代码库,请将警告变成错误。 -
@Davislor 不,它不是“候选函数不可行:第一个参数没有从 'struct _IO_FILE *' 到 'char *' 的已知转换”
-
@Davislor 呵呵,这可能适用于古代 C,但绝对不适用于 C++。
-
@Quentin 是的。那不应该编译。预期的挑战可能是,“获取这个损坏的代码,读懂我的想法,了解它应该做什么,然后修复它”,但在这种情况下应该有一个真正的规范。带有测试用例。
-
我很惊讶没有人尝试过这个,但是
gets(stdin )(带有额外的空格)会产生预期的 C++ 错误。
标签: c++ input gets standards-compliance