14

我正在(快速)编写一些代码,并意外地反转了以下参数scanf()

char i[] = "ABC1\t";
scanf(i, "%s");

编译gcc -Werror -Wall -Wextra并不会抱怨这一点。显然,这段代码不起作用,但为什么 gcc 没有通知我我倒置了参数?它不能检测到i不是格式字符串,或者第二个参数不是可存储类型吗?

编辑
感谢大家的洞察力,看起来我找到了答案,-Wformat旗帜上有一个扭曲,使这个“可捕获”(发布在下面以供参考)

4

3 回答 3

18

哈!我找到了。-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.

于 2012-10-25T12:47:15.787 回答
8

我想它不应该。

int scanf ( const char * format, ... );

i通常转换为 a const char*,所有其余参数都只是“省略号”,无法在编译时检查。

于 2012-10-25T12:37:49.727 回答
3

scanf (man scanf) 的手动输入给出了原型:

int scanf(const char *format, ...);

char[] 只是 char * 的一种特殊类型,因此满足第一个参数。次要参数是在运行时评估的(如果我记得的话),所以这里的编译器甚至不考虑它们。从编译器的角度来看,这是对给定原型的函数的良好调用。

此外,编译器从不检查您是否尝试写入无效位置。关于 C 的伟大(或可怕)的事情是它可以让你或多或少地做你想做的事,即使你想要的是一个坏主意。

于 2012-10-25T12:40:39.563 回答