scanf()中的反转参数
我(很快)编写了一些代码并意外地反转了scanf()
的参数:
char i[] = "ABC1\t"; scanf(i, "%s");
使用gcc -Werror -Wall -Wextra
编译并没有抱怨这一点。 显然,这段代码不起作用,但为什么没有gcc告诉我,我颠倒了参数? 它不能检测到i
不是格式字符串,或者第二个参数不是可存储类型吗?
编辑
感谢所有的洞察力,看起来我找到了答案, -Wformat
标志上有一个扭曲使得这个“可捕获”(在下面发布以供参考)
哈! 我找到了。 用-Wformat=2
标志击中gcc就抓住了它。
发布信息供他人参考:
这是我找到的标志列表
-Wformat Check calls to printf and scanf, etc., to make sure that the arguments supplied have types appropriate to the format string specified...
我曾经假设-Wall
在其中有-Wformat
,它确实如此,但关于我刚发现的内容真正重要的部分:
-Wformat is included in -Wall. For more control over some aspects of format checking, the options -Wformat-y2k, -Wno-format-extra-args, -Wno-format-zero-length, -Wformat-nonliteral, -Wformat-security, and -Wformat=2 are available, but are not included in -Wall.
我想它不应该。
int scanf ( const char * format, ... );
i
通常转换为const char*
,所有其余参数只是“省略号”,在编译时无法检查。
scanf(man scanf)的手动输入给出了原型:
int scanf(const char *format, ...);
char []只是一种特殊类型的char *,因此满足第一个参数。 辅助参数在运行时进行评估(如果我记得的话),因此编译器甚至不会考虑它们。 从编译器的角度来看,这是给出其原型的函数的一个很好的调用。
此外,编译器从不检查您是否尝试写入无效位置。 关于C的伟大(或可怕)的事情是它会让你或多或少地做你想做的事情,即使你想要的是一个坏主意。