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

Sir*_*Guy 21 c printf gcc string-formatting gcc-warning

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

sprintf(someString, "");
Run Code Online (Sandbox Code Playgroud)

这解释了为什么这是警告(在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;
}
Run Code Online (Sandbox Code Playgroud)

打印出来的

'''a'
Run Code Online (Sandbox Code Playgroud)

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

R..*_*R.. 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;(后者更短,更快,更清晰).

  • 我同意,但GCC会发出更多令人讨厌的警告.这绝对是一个较小的进攻.更大的一个是在未使用的函数参数上发出警告,这是*不可避免的*每当你使用必须符合特定签名的函数指针时. (3认同)
  • 我同意这样做会更好,我只是不知道是否有比认为警告更充分的理由。我当然没有权限,但是我认为合理编程的这种特殊冒犯不会被认为值得警告。 (2认同)
  • 虽然警告对文字 `printf` 和 `sprintf` 调用很有用,但不幸的是,同样的警告适用于任何使用“看起来像 printf”属性的用户定义函数。此类用户定义函数可以具有其他效果(例如打印前缀或终止),即使字符串为空也很有用。 (2认同)

And*_*als 5

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