Cast the numbers to the correct types:
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));
Question
i have this line in my code
`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);`
this is the warning i get with gcc while compiling it
`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’
what am i doing wrong??
PS - i have included time.h
and sys/time.h
Solution
Cast the numbers to the correct types:
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));
OTHER TIPS
The type of the members of struct timeval will vary from system to system. As with many other C data types, the safe and portable thing to do is to cast the values when printing them:
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);
This will work correctly for any data type smaller than or equal in size to a long. And this idiom is so common that people will think twice about making any of these common data types longer than a long, although be careful with data types that refer to file sizes (like off_t); those could be long long
in some cases.
To be maximally safe, you'd cast to long long
and use a %lld
format, but that swaps one portability problem for another, since not all printf
implementations support %lld
yet. And I've not seen an implementation where those time values require that treatment.
See sys/types.h for an explanation of suseconds_t
. Apparently, it is
a signed integral type capable of storing values at least in the range [-1, 1,000,000].
This means it might defined as an int
on your system. Try removing the long specifier l
from the format string and just print it as a regular decimal.
Edit
As per rra's answer, this will not be portable. It will only work on systems that define suseconds_t
in the same way. We know from the spec that the type is a signed integral type of at least 32 bits. The most portable way is to cast it to the biggest signed integral intrinsic that you can get away with.