Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 18 Jan 2013 06:03:39 +0100
From:      Polytropon <freebsd@edvax.de>
To:        "Thomas D. Dean" <tomdean@speakeasy.org>
Cc:        "questions@FreeBSD.org" <questions@freebsd.org>
Subject:   Re: time_t definition
Message-ID:  <20130118060339.7b12ad34.freebsd@edvax.de>
In-Reply-To: <50F8D3A1.6090104@speakeasy.org>
References:  <50F5A189.7000701@speakeasy.org> <20130116120015.3b8d0db4@mr129166> <50F6EDFB.70501@speakeasy.org> <CAHu1Y71L0fuQPgN044-GDr8NBPAo=n%2B6HSBv7Zi%2ByXTceYTZCA@mail.gmail.com> <20130117011721.69799ef6.freebsd@edvax.de> <44622vx4ys.fsf@lowell-desk.lan> <50F8D3A1.6090104@speakeasy.org>

next in thread | previous in thread | raw e-mail | index | archive | help
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, ...



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20130118060339.7b12ad34.freebsd>