2

我的代码中有这一行

`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.hsys/time.h

4

3 回答 3

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 的任何数据类型都可以正常工作。而且这个习语是如此普遍,以至于人们会三思而后行,使任何这些常见数据类型的长度都超过 long,尽管要小心引用文件大小的数据类型(如 off_t);long long在某些情况下可能是这样。

为了最大程度地安全,您将转换为long long并使用一种%lld格式,但这会将一个可移植性问题换成另一个,因为并非所有printf实现都支持%lld。而且我还没有看到那些时间值需要这种处理的实现。

于 2013-03-18T01:55:56.980 回答
2

将数字转换为正确的类型:

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));
于 2013-03-18T01:56:59.327 回答
1

请参阅sys/types.h以了解suseconds_t. 显然,它是

一种有符号整数类型,能够存储至少在 [-1, 1,000,000] 范围内的值。

int这意味着它可能在您的系统上定义为一个。尝试l从格式字符串中删除长说明符,然后将其打印为常规小数。

编辑

根据 rra 的回答,这将不可移植。它仅适用suseconds_t于以相同方式定义的系统。我们从规范中知道该类型是至少 32 位的有符号整数类型。最便携的方法是将其转换为您可以逃脱的最大有符号积分内在函数。

于 2013-03-18T01:50:12.563 回答