提问者:小点点

Re 遗留代码:格式 '%d' 需要类型为 'int' 的参数,但参数 3 的类型为 'long unsigned int' [-Wformat]


我经常尝试用最近的GCC构建很多旧的模拟器和磁盘和磁带存档工具。有些错误很容易修复,但我不是一个很好的程序员。

我得到:

itstar.c:在函数“addfiles”中:
itstar.c:194:4:警告:格式“%d”需要类型为“int”的参数,但参数2的类型为“long unsigned int”[-Wformat]
its tar.c:19:4:警告:格式为“%d”的参数需要类型为”int“,但参数3的类型为”long unsgned int“[-Wformat]

从这个代码片段:

/* add files to a DUMP tape */
/* output buffer must have been initialized with resetbuf() */
static void addfiles(int argc,char **argv)
{
    int c=argc;
    char **v=argv;

    while(c--) {
        addfile(argc,argv,*v++);
    }
    if(verify)
        printf("Approximately %d.%d' of tape used\n",count/bpi/12,
            (count*10/bpi/12)%10);
}

其中第194行是倒数第三行,以printf开头。

文件是itstar. c,来自Tapetools,代码在这里。

尽管有警告,它还是会构建,但我更希望知道如何防止它,< br >因此结果更有效,数据损坏的可能性也更小。

拜托,我错过了什么,需要改变吗?

提前谢谢你。


共3个答案

匿名用户

使用格式说明符< code>%lu而不是< code>%d,编译器应该会停止抱怨。

printf("Approximately %lu.%lu' of tape used\n", count/bpi/12, (count*10/bpi/12)%10);

匿名用户

这是未定义的行为,这意味着任何事情都可能发生,包括看起来正常工作,然后在以后的道路上发生故障。

查看源代码,我们可以看到< code>count和< code>bpi都是无符号长整型:

extern unsigned long bpi; /* tape density in bits per inch */
extern unsigned long count; /* count of tape frames written */ 

这些的正确格式说明符是%lu

printf的第一个参数指定要打印的字符串,该字符串可以包含以< code>%开头的转换说明符,通常指定后续参数的类型,因此在您的示例中:

"Approximately %d.%d' of tape used\n"
               ^^ ^^
               1  2

转换说明符12都是%d,这意味着printf将期望接下来的两个参数是int类型,但它们实际上是无符号长类型。

如果我们看一下 C99 标准草案第 7.19.6.1 节 fprintf 函数也涵盖了格式说明符的 printf,说:

如果转换规范无效,则行为未定义。248)如果任何参数不是相应转换规范的正确类型,则行为未定义。

因此,您需要修复不正确的格式说明符,您的警告将消失,您将回到定义明确的行为领域。

匿名用户

使用%lu而不是%d%d用于类型int%lu则用于无符号long。