Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 20 Jan 2013 23:07:23 -0500
From:      Garance A Drosehn <gad@FreeBSD.org>
To:        "Thomas D. Dean" <tomdean@speakeasy.org>
Cc:        "questions@FreeBSD.org" <questions@FreeBSD.org>
Subject:   Re: time_t definition
Message-ID:  <50FCBEFB.3010102@FreeBSD.org>
In-Reply-To: <50F6EDFB.70501@speakeasy.org>
References:  <50F5A189.7000701@speakeasy.org> <20130116120015.3b8d0db4@mr129166> <50F6EDFB.70501@speakeasy.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On 1/16/13 1:14 PM, Thomas D. Dean wrote:
> On 01/16/13 03:00, Patrick Lamaiziere wrote:
>
>> Looks like gcc47 checks the printf format string (-Wformat)
>> Disable this check or convert your time_t.
>
> Yes, I know gcc47 checks the format string.
>
> But, time_t is of type int32, from a typedef statement.
>
>
> #include <stdio.h>
> typedef int zzz;
> typedef zzz yyy;
> typedef yyy xxx;
> int main() {
> xxx idx;
> for (idx=0; idx<10; idx++) printf("%d\n",idx);
> return 0;
> }
>
> does not produce the error (I did this on the 'other' system)
>  > gcc --version
> gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
> ...
>
>  > gcc -O2 -pipe -I../../include -std=gnu99 -fstack-protector
> -Wsystem-headers -Werror -Wall -Wno-format-y2k -Wno-uninitialized
> -Wno-pointer-sign xxx.c -o xxx
>
> I did not think to do this on the FreeBSD system I was using yesterday.
>
> What I don't understand is where gcc is losing track of this definition.
>
> In 9.0, or maybe earlier, the definition of time_t was changed with a
> view toward 64-bit systems. I remember a statement to the effect of "in
> 2038, 32-bit time will overflow. It is unlikely that many 32-biot
> systems will be around then. So, making the change to 64-bit now will
> prevent having to do it in the future".
>
> So, now, it seems that any calculation involving time_t requires a cast????

I'm the freebsd developer who changed time_t *ON SPARC64* to be a
64-bit value.  We did not change it on the i386 platform.  We did
go with a 64-bit value for the AMD64 platform, so your example would
work on amd64 but not on i386.

Also, depending on the platform and the compiler you're using,
"long int" is not the same as "int".  In your example, time_t
is explicitly set to a 32-bit integer, but you'll find that
"long int" on your platform is a 64-bit integer.  On some other
platforms it may be true that "long int" is a 32-bit integer,
but it is not on the platform you are on.

When it comes to C data types, a 32-bit integer is not the same
as a 64-bit integer.  This is especially important when passing
parameters when calling other routines.  The format in the
printf statement uses '%ld', which matches "long int".

The warning from the compiler is correct.  It has not lost track
of anything.  It is looking exactly at what your platform uses,
and warning you that the printf in question will not work the way
that you almost certainly want it to work.

Yes, this means that the only reliable way to printf a time_t is
to use a cast.  That has been true for at least a decade.  It may
be true that you happened to avoid this issue before, but the only
*RELIABLE* platform-independent way to print time_t's is via a cast.

-- 
Garance Alistair Drosehn            =   gad@gilead.netel.rpi.edu
Senior Systems Programmer           or  gad@freebsd.org
Rensselaer Polytechnic Institute    or  drosih@rpi.edu



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?50FCBEFB.3010102>