【发布时间】:2017-01-17 20:07:21
【问题描述】:
这个问题很简单,s 是一个字符串,我突然想到尝试使用printf(s) 看看它是否有效,在一种情况下我收到警告,在另一种情况下没有。
char* s = "abcdefghij\n";
printf(s);
// Warning raised with gcc -std=c11:
// format not a string literal and no format arguments [-Wformat-security]
// On the other hand, if I use
char* s = "abc %d efg\n";
printf(s, 99);
// I get no warning whatsoever, why is that?
// Update, I've tested this:
char* s = "random %d string\n";
printf(s, 99, 50);
// Results: no warning, output "random 99 string".
那么printf(s) 和printf("%s", s) 之间的根本区别是什么?为什么我只会在一种情况下收到警告?
【问题讨论】:
-
真的很惊喜,也很有趣。我确认了这种行为,可能会有解释,但在有人解释之前,我认为这是诊断中的错误。
-
@JoachimPileborg,所以您是说通过不提供字符串文字,编译器无法知道需要多少个参数?所以这就是为什么如果我不再提供参数,我会收到警告,但如果我至少提供一个,我不会。我在这个问题上又添加了一个例子,我想它支持我所说的。
-
如果你也使用
const char* const s,你可能会注意到不同。 -
另一个区别是编译时分析和优化然后应用 - 或不能。
-
根本区别在于
printf(s)是一个等待发生的错误(以及潜在的security hole),而printf("%s", s)只是编写fputs(s, stdout)的一种低效方式。
标签: c string printf compiler-warnings format-specifiers