我的代码中有这一行
`printf("Rcvd pkt from %s:%d at <%ld.%06ld>\n", inet_ntoa(servAddr.sin_addr), ntohs(servAddr.sin_port), timeVal.tv_sec, timeVal.tv_usec);`
这是我在编译时使用gcc的警告
`cc1: warnings being treated as errors
`client12.c: In function ‘main’:
`client12.c:131: warning: format ‘%06ld’ expects type ‘long int’, but argument 5 has type ‘__darwin_suseconds_t’
`client12.c:131: warning: format ‘%06ld’ expects type ‘long int’, but argument 5 has type ‘__darwin_suseconds_t’
我做错了什么?
PS - 我已加入time.h
和sys/time.h
答案 0 :(得分:2)
struct timeval成员的类型因系统而异。与许多其他C数据类型一样,安全和便携的事情是在打印时转换值:
printf("Rcvd pkt from %s:%d at <%ld.%06ld>\n",
inet_ntoa(servAddr.sin_addr), ntohs(servAddr.sin_port),
(long) timeVal.tv_sec, (long) timeVal.tv_usec);
对于任何小于或等于long的数据类型,这都可以正常工作。这个习惯用法非常普遍,以至于人们会考虑使这些常见数据类型的长度超过很长时间,但要注意引用文件大小的数据类型(如off_t);在某些情况下,这些可能是long long
。
为了最大限度地安全,您将转换为long long
并使用%lld
格式,但这会将另一个可移植性问题转换为另一个,因为并非所有printf
实现都支持{{1但是。而且我没有看到那些时间值需要处理的实现。
答案 1 :(得分:1)
有关suseconds_t
的说明,请参阅sys/types.h。显然,它是
有符号整数类型,能够存储至少在[-1,1,000,000]范围内的值。
这意味着它可能在您的系统上定义为int
。尝试从格式字符串中删除长说明符l
,然后将其打印为常规小数。
修改强>
根据rra的回答,这不可移植。它仅适用于以相同方式定义suseconds_t
的系统。我们从规范中知道该类型是至少32位的有符号整数类型。最便携的方法是将它转换为你可以逃脱的最大的签名积分内在。
答案 2 :(得分:1)
将数字转换为正确的类型:
printf("Rcvd pkt from %s:%d at <%ld.%06ld>\n", inet_ntoa(servAddr.sin_addr), ntohs(servAddr.sin_port), (long int)(timeVal.tv_sec), (long int)(timeVal.tv_usec));