我正在(快速)编写一些代码,并意外地反转了以下参数scanf()
:
char i[] = "ABC1\t";
scanf(i, "%s");
编译gcc -Werror -Wall -Wextra
并不会抱怨这一点。显然,这段代码不起作用,但为什么 gcc 没有通知我我倒置了参数?它不能检测到i
不是格式字符串,或者第二个参数不是可存储类型吗?
编辑
感谢大家的洞察力,看起来我找到了答案,-Wformat
旗帜上有一个扭曲,使这个“可捕获”(发布在下面以供参考)
我正在(快速)编写一些代码,并意外地反转了以下参数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
通常转换为 a const char*
,所有其余参数都只是“省略号”,无法在编译时检查。
scanf (man scanf) 的手动输入给出了原型:
int scanf(const char *format, ...);
char[] 只是 char * 的一种特殊类型,因此满足第一个参数。次要参数是在运行时评估的(如果我记得的话),所以这里的编译器甚至不考虑它们。从编译器的角度来看,这是对给定原型的函数的良好调用。
此外,编译器从不检查您是否尝试写入无效位置。关于 C 的伟大(或可怕)的事情是它可以让你或多或少地做你想做的事,即使你想要的是一个坏主意。