我四处搜索了一下这方面的信息,但没有找到令人满意的信息。函数调用有什么特殊行为吗
sprintf(someString, "");
这解释了为什么这是警告(在带 -Wall 的 gcc 上)?我只是设法发现 C 标准允许零长度格式字符串。
我尝试了以下示例
#include <stdio.h>
int main()
{
char str[2] = {'a', 'a'};
sprintf(str, "");
printf("\'%c\'\'%c\'\n", str[0], str[1]);
return 0;
}
打印出来
'''a'
这正是我所期望看到的。 那么,为什么会出现警告?
GCC 发出警告的事实通常与该构造是否是合法的 C 无关,而是与 GCC 开发人员是否认为它可能表明您的意思与所写的内容不同,或者只是糟糕的风格有关。以下是一些示例:
if (x = 0)
— 你几乎肯定是指 if (x == 0)
。printf(str)
— 您几乎肯定是指 fputs(str, stdout)
或 printf("%s", str)
;正如所写,该代码非常危险。if (foo == bar & MASK)
— 你几乎肯定是指 if (foo == (bar & MASK))
。等等
就您而言,我认为 GCC 正在质疑为什么您要调用
sprintf(String, "")
来执行与 String[0]=0;
相同的操作(后者更短、更快、更清晰)。
您收到警告是因为 gcc 知道
sprintf()
的第二个参数应该是一个非空字符串,通常具有各种格式规范 - 与您正在执行的操作在功能上等效且“更合法”的调用你的代码将是sprintf(str, "%s", "")
。此外,几乎总是有 1 到 N 个附加参数,足以满足格式规范。当您在这里使用它时,您将其用作一种 strcpy()
,虽然在技术上是有效的,但使用标准库的方式却非常奇怪。
这只是 GCC 的警告。如果您希望在应用程序的一部分中禁止它,您可以执行以下操作:
#pragma GCC diagnostic ignored "-Wformat-zero-length"
int main()
{
// code that produces a warning
}
#pragma GCC diagnostic warning "-Wformat-zero-length"
-Wall
可以与-Wno-format-zero-length
合法组合,当需要预先消除一些分散在代码中的#define
字符串值时非常有用。
-W格式
选项-Wformat相当于-Wformat=1,-Wno-format相当于-Wformat=0。由于 -Wformat 还检查多个函数的空格式参数,因此 -Wformat 也意味着 -Wnonnull。
可以通过以下选项禁用此级别的格式检查的某些方面:-Wno-format-contains-nul、-Wno-format-extra-args 和 -Wno-format-zero-length。 -Wformat 由 -Wall 启用。