time_t definition
Polytropon
freebsd at edvax.de
Fri Jan 18 05:03:39 UTC 2013
On Thu, 17 Jan 2013 20:46:25 -0800, Thomas D. Dean wrote:
> A lot of discussion about what I can do other than understand why gcc
> does not keep track of the basic typedef.
As explained, gcc issues a valid (!) warning because there
was a type mismatch: You tried to printf() a (long) value
with %ld, but a (int) value (requiring %d) was supplied to
the function.
It's not gcc's job to advice the programmer on what he should
do. You _intendedly_ write something, and the compiler treats
your words as truth. If you formulate something wrong, the
compiler will complain, and that's okay. Warnings are a good
means to deal with such "minor errors".
> Mayhe the question is beyond this list.
Allow me to repeat, just to be sure I haven't missed an
important point:
gcc47 -O2 -pipe -I../../include -std=gnu99 -fstack-protector
-Wsystem-headers -Werror -Wall -Wno-format-y2k -Wno-uninitialized
-Wno-pointer-sign -c data-collection.c
data-collection.c: In function 'main':
data-collection.c:214:4: error: format '%ld' expects argument of type
'long int', but argument 3 has type 'time_t' [-Werror=format]
data-collection.c:234:4: error: format '%ld' expects argument of type
'long int', but argument 3 has type 'time_t' [-Werror=format]
cc1: all warnings being treated as errors
*** [data-collection.o] Error code 1
The compiler option -Werror=format informs you:
format '%ld' expects argument of type 'long int',
but argument 3 has type 'time_t'
That matches the source:
gettimeofday(&spi_stop, &tz); / * line 211 */
printf("Loop %d, SPI %ld %ld\n",
loop,
spi_stop.tv_sec, spi_stop.tv_usec);
gettimeofday(&disk_stop, &tz); /* line 231 */
printf("Loop %d, Disk %ld %ld\n",
loop,
disk_stop.tv_sec, disk_stop.tv_usec);
disk_stop.tv_sec and disk_stop.tv_usec are (timt_t).
You've properly included the include files for time_t variables.
There are "recursive typedefs" as follows:
/usr/src/sys/sys/types.h (line 253):
typedef __time_t time_t;
/usr/src/sys/i386/include/_types.h (line 97):
typedef __int32_t __time_t;
/usr/src/sys/i386/include/_types.h (line 55):
typedef int __int32_t;
In the end, you have this "type chain":
int -> __int32_t --> __time_t -> time_t
Or in the reverse order:
time_t -> __time_t -> __int32_t -> int
So _at least here_ (!), (time_t) is equivalent to (int).
Repeating: In your format string, you request a position for a
(long) argument, but gcc encounters an (int) value instead and
validly issues the proper warning.
So to speak, you're "doing something wrong here". You can avoid
the problem by typecasting the (time_t) values to (long):
printf("Loop %d, SPI %ld %ld\n",
loop,
(long)spi_stop.tv_sec, (long)spi_stop.tv_usec);
Or you can change the format parameter to %d:
printf("Loop %d, SPI %d %d\n",
loop,
spi_stop.tv_sec, spi_stop.tv_usec);
However, the "most clean" solution is to combine both methods:
Cast the (time_t) values to (int) _and_ use the %d placeholder:
printf("Loop %d, SPI %d %d\n",
loop,
(int)spi_stop.tv_sec, (int)spi_stop.tv_usec);
The reason is simple: You should not blindly _rely_ on the
assumtion that (time_t) which you know is "some integer type"
is _exactly_ (int) -- it doesn't neccessarily have to be.
Similarly, you shouldn't assume that it's (long) either.
I hope this verbose explanation has been easy to understand.
--
Polytropon
Magdeburg, Germany
Happy FreeBSD user since 4.0
Andra moi ennepe, Mousa, ...
More information about the freebsd-questions
mailing list