【问题标题】:snprintf - format not a string literal and no format arguments warningsnprintf - 格式不是字符串文字并且没有格式参数警告
【发布时间】:2013-04-07 08:12:19
【问题描述】:

我在 Linux 上编译它时收到 format not a string literal and no format arguments 警告。 snprintf 为第三个参数显示 const char*。定义const char *INTERFACE = "wlan0"然后将其传递给函数有什么问题?

#include <stdio.h>
#include <net/if.h>
#include <string.h>

int main(int argc,char *argv[]){
    const char *INTERFACE        = "wlan0";
    struct ifreq ifr;

    memset(&ifr, 0, sizeof(ifr));
    snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), INTERFACE);

  return 0;
}

【问题讨论】:

  • 我没有收到任何警告:ideone.com/BdSQF2 似乎没问题
  • 它是const char *format,看起来像“%s”
  • 你有什么版本的 GCC? (只需运行gcc -v 即可了解)。
  • 我猜你的 GCC 可能早于 4.7;那么升级你的编译器可能是值得的......(例如到 GCC 4.8)。
  • gcc version 4.7.2 (Ubuntu/Linaro 4.7.2-2ubuntu1),谢谢提示

标签: c linux gcc posix printf


【解决方案1】:

没有错(这就是为什么它是警告而不是错误),只是printf 系列函数最常见的用法是使用literal 格式字符串。

喜欢:

snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", INTERFACE);

在您的情况下,您可能应该使用例如memcpy 改为:

#define MIN(a, b) ((a) < (b) ? (a) : (b))

memcpy(ifr.ifr_name, INTERFACE, MIN(strlen(INTERFACE) + 1, sizeof(ifr.ifr_name));

还有strncpy 可能会起作用,但在某些情况下它不会添加终止'\0' 字符。

【讨论】:

    【解决方案2】:

    警告的后半部分(“并且没有格式参数”)表示该字符串不包含任何%s,因此像您正在使用的那样使用snprintf() 是没有意义的。

    值得警告,因为它可能存在安全风险,如果字符串参数在运行时可更改,则% 可能会“潜入”,这将导致问题。因此,最好将格式化字符串硬编码为“做你想做的事”。

    如前所述,在这种情况下使用snprintf() 毫无意义。

    【讨论】:

    • +1 用于提及安全风险。惯用用法(如果你真的必须使用 snprintf)应该是 snprintf(str, sizeof(str), "%s", foo);
    【解决方案3】:

    这只是一个警告,所以你可以忽略它。

    但在您的情况下不值得使用snprintf ,只需代码

      strncpy (ifd.ifr_name, sizeof(ifr.ifre_name), INTERFACE);
    

    这可能会运行得更快,更重要的是不要发出警告。如果您想确保名称以 null 结尾,请使用 ifd.ifr_name[sizeof(ifr.ifre_name)-1] = (char)0; 强制它

    顺便说一句,使用最近的 GCC 4.8,并使用 gcc-4.8 -Wall sven.c -o sven 编译我没有收到任何警告。即使是gcc-4.7 -Wall。这可能是&lt;stdio.h&gt; 中的libc 标头问题...

    【讨论】:

      猜你喜欢
      • 2010-12-13
      • 2011-05-24
      • 2015-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-23
      • 2011-08-12
      • 1970-01-01
      相关资源
      最近更新 更多