我经常尝试用最近的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 >因此结果更有效,数据损坏的可能性也更小。
拜托,我错过了什么,需要改变吗?
提前谢谢你。
使用格式说明符< 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
转换说明符1
和2
都是%d
,这意味着printf
将期望接下来的两个参数是int
类型,但它们实际上是无符号长
类型。
如果我们看一下 C99 标准草案第 7.19.6.1
节 fprintf 函数也涵盖了格式说明符的 printf,说:
如果转换规范无效,则行为未定义。248)如果任何参数不是相应转换规范的正确类型,则行为未定义。
因此,您需要修复不正确的格式说明符,您的警告将消失,您将回到定义明确的行为领域。
使用%lu
而不是%d
%d
用于类型int
,%lu
则用于无符号long。