【问题标题】:gcc with -Wformat option prints warning for const unsigned char带有 -Wformat 选项的 gcc 为 const unsigned char 打印警告
【发布时间】:2018-02-06 16:26:29
【问题描述】:

测试代码:

#include <stdio.h>

int main(int argc, char **argv) {

    char buf[10];

    char c[] = "%i";
    unsigned char uc[] = "%i";
    const char cc[] = "%i";
    const unsigned char cuc[] = "%i";
    const unsigned char *cucp = "%i";

    sprintf(buf, (char *)c, 1);
    sprintf(buf, (char *)uc, 1);
    sprintf(buf, (char *)cc, 1);
    sprintf(buf, (char *)cuc, 1);
    sprintf(buf, (char *)cucp, 1);

    return 0;
}

编译:

gcc -Wformat -o test test.c
test.c: In function ‘main’:
test.c:16:26: warning: format is a wide character string [-Wformat=]
    sprintf(buf, (char *)cuc, 1);
                         ^

为什么我会收到 const unsigned char 的警告,而其他类型却没有?

使用 gcc 5.4.0 和一些跨 gcc 4.3.2 测试。 解释可能包括不同数据类型存储在哪些段中,但我很惊讶。

【问题讨论】:

  • 我没有看到带有 clang 的警告。对我来说似乎是 GCC 问题。
  • @PaulFloyd,您需要打开警告。 'clang' 使用'gcc',所以可用的警告(大部分)是相同的。建议:-Wall -Wextra -Wconversion -pedantic -std=gnu11 这将导致 4 个警告。其中两个警告是关于未使用的参数 argcargv 然后是关于这一行的警告:const unsigned char *cucp = "%i";(初始化中的指针目标在符号上不同)然后是关于这一行的警告:sprintf(buf, (char *)cuc, 1);(格式很宽字符串)
  • cont:所以您的警告(您确实需要启用更多警告)代码声明了一个无符号字符,但结果在调用 sprintf() 时被强制转换为有符号字符。在任何情况下,引用“格式字符串”都是一种安全风险。最好将“格式字符串”放在参数中
  • 用另一个编译器测试是个好主意。但我不认为clang使用gcc,我无法用clang重现警告。对我来说也像是一个 gcc 问题。我已经提交了bug report
  • @user3629249 我不确定您所说的“'clang' 使用'gcc'”是什么意思。也许您指的是使用 GCC 作为前端的 Apple llvm GCC 编译器。常规 llvm/clang 使用或多或少兼容的命令行开关,但相似之处到此为止。编译器资源管理器上的 clang 5 产生 9 个带有 -Weverything 的警告,但没有关于宽字符串的警告。

标签: c gcc compiler-warnings


【解决方案1】:

它现在是一个已确认的 gcc bug,应该很快就会修复。

顺便说一句:它是在 2000 年 9 月 24 日推出的。

【讨论】:

    猜你喜欢
    • 2012-07-03
    • 2020-02-16
    • 1970-01-01
    • 2016-05-29
    • 1970-01-01
    • 2011-02-04
    • 2010-09-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多