为什么gcc -Wall会给出关于零长度格式字符串的警告?

时间:2012-03-29 13:47:08

标签: c gcc string-formatting printf gcc-warning

我搜索了一下这方面的信息,但没有找到任何令人满意的结果。函数调用是否有一些特殊的行为

sprintf(someString, "");

这解释了为什么这是警告(在gcc上使用-Wall)?我只是发现C标准允许零长度格式字符串。

我尝试了以下示例

#include <stdio.h>

int main()
{
    char str[2] = {'a', 'a'};
    sprintf(str, "");
    printf("\'%c\'\'%c\'\n", str[0], str[1]);
    return 0;
}

打印出来

'''a'

这正是我期望看到的。 那么,为什么要警告?

3 个答案:

答案 0 :(得分:23)

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))

在你的情况下,我认为海湾合作委员会质疑为什么你打电话给sprintf(String, "")来做相当于String[0]=0;(后者更短,更快,更清晰)。

答案 1 :(得分:5)

你收到了警告,因为gcc知道sprintf()的第二个参数应该是一个非空字符串,通常是一个具有各种格式规范的字符串 - 一个功能相同的“和更合法”的调用你的那个你代码中的代码是sprintf(str, "%s", "")。此外,几乎总有一到N个额外的参数,足以满足格式规范。当你在这里使用它时,你将它用作strcpy()的一种,虽然技术上有效,但使用标准库是一种非常奇怪的方式。

答案 2 :(得分:4)

这只是海湾合作委员会的警告。如果您希望在应用程序的某个部分禁止它,可以执行以下操作:

#pragma GCC diagnostic ignored "-Wformat-zero-length"
int main()
{
     // code that produces a warning
}
#pragma GCC diagnostic warning "-Wformat-zero-length"