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

问题描述 投票:0回答:4

我四处搜索了一下这方面的信息,但没有找到令人满意的信息。函数调用有什么特殊行为吗

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'

这正是我所期望看到的。 那么,为什么会出现警告?

c gcc string-formatting printf gcc-warning
4个回答
29
投票

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;
相同的操作(后者更短、更快、更清晰)。


8
投票

您收到警告是因为 gcc 知道

sprintf()
的第二个参数应该是一个非空字符串,通常具有各种格式规范 - 与您正在执行的操作在功能上等效且“更合法”的调用你的代码将是
sprintf(str, "%s", "")
。此外,几乎总是有 1 到 N 个附加参数,足以满足格式规范。当您在这里使用它时,您将其用作一种
strcpy()
,虽然在技术上是有效的,但使用标准库的方式却非常奇怪。


4
投票

这只是 GCC 的警告。如果您希望在应用程序的一部分中禁止它,您可以执行以下操作:

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

0
投票

-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 启用。

这是来源

© www.soinside.com 2019 - 2024. All rights reserved.