[net.unix-wizards] 4.2BSD ctime

sloane@noscvax.UUCP (04/09/84)

Whenever I use gmtime() lint complains about arguments, saying that
the 1st argument to gmtime() is used inconsistently. I mucked about
and found the following:

	from 'man ctime':     

           struct tm *gmtime(clock);
           long *clock;

	from /usr/lib/lint/llib-lc:	
		
		struct tm * gmtime(c) time_t *c {returns gmtime(c)}

	from /usr/include/sys/types.h:
		
		typedef int time_t;
			 
This seems to indicate that the argument to gmtime() should be of type
time_t (according to llib-lc) which is an int (according to sys/types.h)
rather than a long (as man ctime would lead one to believe).

Compiling my program with the argument declared as an int both worked
and stopped lint from complaining. Is the man page in error or am I
hopelessly lost? And is it safe to use an int for the argument to
gmtime()?


      Gary K. Sloane
      c/o Naval Ocean Systems Center
      COTD Building 1 Room B205
      San Diego, California 92152

      MILNET: sloane@nosc
      UUCP:   ...{sdcsvax}!nosc-cc!sloane
      DDD: (619) 225-8401 x391

gwyn@brl-vgr.ARPA (Doug Gwyn ) (04/11/84)

time_t is definitely a long, not an int.  You need to remember that
the BSD developers did not pay much attention to the distinction.

olson@fortune.UUCP (04/12/84)

#R:noscvax:-39800:fortune:11600085:000:876
fortune!olson    Apr 11 12:39:00 1984

>	Is it safe to use a *int as the argument to gmtime() instead of
>	a *long.

The answer is yes on machines that have 32bit ints, but the code won't
be portable to machines that have 16bit ints.

The BSD (and for that matter V7 and S3) man pages and include files
are full of this kind of carelessness.  BSD especially is guilty of
referring to 'words' sometimes meaning shorts and sometimes meaning
longs.

One of the classic cases is the wait(2) man page referring to
the high byte and the low byte, when actually it is the low order byte
and the 'next to low' order byte.  (Also see some of the ioctls under
tty(4).)  Some of the man pages were not rewritten from the V7,
and other man pages were written with the (unstated) assumption that
they were for the VAX.

	Dave Olson, Fortune Systems
	UUCP: {ihnp4,ucbvax!amd70}!fortune!olson
	ARPA: amd70!fortune!olson@BERKELEY

henry@utzoo.UUCP (Henry Spencer) (04/13/84)

Gary K. Sloane observes:

   Whenever I use gmtime() lint complains about arguments, saying that
   the 1st argument to gmtime() is used inconsistently. I mucked about
   and found the following:

   	from 'man ctime':     

              struct tm *gmtime(clock);
              long *clock;

   	from /usr/lib/lint/llib-lc:	
   		
   		struct tm * gmtime(c) time_t *c {returns gmtime(c)}

   	from /usr/include/sys/types.h:
   		
   		typedef int time_t;
   			 
   This seems to indicate that the argument to gmtime() should be of type
   time_t (according to llib-lc) which is an int (according to sys/types.h)
   rather than a long (as man ctime would lead one to believe).

   Compiling my program with the argument declared as an int both worked
   and stopped lint from complaining. Is the man page in error or am I
   hopelessly lost? And is it safe to use an int for the argument to
   gmtime()?

NO NO NO NO NO!!!!  The argument to gmtime() should be of type "time_t",
and ***ONLY*** time_t.  Just exactly what kind of int time_t is, is
something that is machine-dependent and system-dependent; you are not
supposed to imbed such assumptions into your programs!

The manual page is a bit out of date.  The lint library is correct.
The include file is machine-dependent and 4.2BSD-dependent.  (And the
turkeys at Berkeley have botched it again -- it *should* have been
"typedef long time_t"!  It makes no actual difference on the VAX, but
it makes the portability situation a lot clearer.  There are a *LOT*
of Unix machines where time_t is not int.)

Note that using "long" is wrong too.  There are machines where time_t
is not the same as long.

It is admitted that this slightly confused situation does cause
difficulties sometimes, especially when it's time to do arithmetic or
i/o on time_t values.  All you can do is try to use time_t whenever
you can, and mark deviations from this as "machine-dependent".
-- 
				Henry Spencer @ U of Toronto Zoology
				{allegra,ihnp4,linus,decvax}!utzoo!henry

ado@elsie.UUCP (04/16/84)

Henry Spencer notes:
	. . .The argument to gmtime() should be of type "time_t",
	and ***ONLY*** time_t.  Just exactly what kind of int time_t is, is
	something that is machine-dependent and system-dependent; you are not
	supposed to imbed such assumptions into your programs!

	The manual page is a bit out of date.  The lint library is correct.
	The include file is machine-dependent and 4.2BSD-dependent. . .it
	*should* have been "typedef long time_t"!  It makes no actual difference
	on the VAX, but it makes the portability situation a lot clearer.
	There are a *LOT* of Unix machines where time_t is not int. . .

The "ctime" manual page on our 4.1 system has "7th Edition" in the
lower-left-hand corner.  I suspect that on "7th Edition" systems the way to call
"ctime" is STILL with a "long *".  I don't know if the "sys/types.h" file in
which "time_t" is "typedef"d is even present on "7th edition" systems.
Is there anyone out there who does?
(And what's the situation on System V with respect to the "ctime" argument?)

On our 4.1 system, the lint library (or the "ctime" source code, take your
pick) is wrong.  The lint library claims that "ctime" takes a "time_t *" as
its argument, where "time_t" has been "typedef"d to be an "int". 
But "ctime.c" reads (in part):
	char *
	ctime(t)
	long *t;
	{ . . .
which says that "ctime" takes a "long *" as its argument.
Maybe this discrepancy has been fixed in 4.2bsd.
Then again, maybe it has been replaced with a new discrepancy.
Can anyone running 4.2 shed light on this?

The bottom lines:  to keep "lint" happy and ensure portability, I'd do this:
	#ifdef vax
	#include <sys/types.h>
	time_t	timearg;
	#else
	long	timearg;
	#endif

--
UNIX is an AT&T (or Bell Labs, or AT&T Bell Labs) trademark.
(Can some AT&T mouthpiece post the preferred form for this note?)
VAX is a Digital Equipment Corporation trademark.
TIME is a Time/Life, Incorporated trademark.
-- 
UUCP:	decvax!harpo!seismo!rlgvax!cvl!elsie!ado
DDD:	(301) 496-5688

ebk@iedl02.UUCP (04/21/84)

On any Unix system I've ever seen, time_t exists and is 32 bits.
<sys/types.h> goes back to v7, and probably further, and defines the necessary
bit widths for certain types, such as time_t, daddr_t (disk address),
caddr_t (core address), etc.  types.h could be made a bit clearer by doing
something like:
#define BIT16 int
#define BIT32 long

typedef time_t BIT32
typedef ino_t BIT16
...
...

For portability, never use int, long, etc., when referring to a system
type - use the entry from sys/types.h

John Owens