Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 27 Oct 1995 11:22:05 -0400
From:      "Garrett A. Wollman" <wollman@lcs.mit.edu>
To:        Dave Andersen <angio@aros.net>
Cc:        freebsd-questions@freebsd.org
Subject:   Re: Help -- Stupid "C" question.
Message-ID:  <9510271522.AA22958@halloran-eldar.lcs.mit.edu>
In-Reply-To: <199510270354.VAA27065@terra.aros.net>
References:  <v02130500acb5df16dbb7@[199.183.109.242]> <199510270354.VAA27065@terra.aros.net>

next in thread | previous in thread | raw e-mail | index | archive | help
Hey, it's portable programming time!

<<On Thu, 26 Oct 1995 21:54:43 -0600 (MDT), Dave Andersen <angio@aros.net> said:

> Time requires a NULL argument to be passed to it.

Actually, let's be slightly more accurate here.

time(3) takes as its only argument a pointer to type `time_t'.  If
that pointer is not null (NB: not `not NULL'), then it fills in that
location with the current time.  In any case, it also returns a value
of type `time_t'.  (Old systems spelled `time_t' l-o-n-g, but you
should use `time_t' and define it yourself if the system doesn't.
FreeBSD always has.)  Depending on your preferred style of
programming, you might want to write either:

	time_t thetime;
	time(&thetime);
or
	time_t thetime;
	thetime = time((time_t *)0);

Note that the `(time_t *)' case is important for portable programs,
unless you can guarantee that a complete prototype of the `time'
function is in scope.  (I consider it to be good style anyway.)  The
second form has the benefit of permitting `thetime' to be stored in a
register.

The reason why `time' works this way goes back to Sixth Edition Unix.
In v6, the `long' type had not yet been added to the C language.  As a
result, all functions dating back to that era which deal with times
originally expected a pointer to the first element of an array of two
`int' elements, and would perform the 32-bit arithmetic by hand.
(Ever wonder about PDP_ENDIAN in <machine/endian.h>?)  When `long' was
added to the language, the calling convention of the time routines was
left the same to ensure binary compatibility.  Of course, `time' could
not return its value directly until the language had `long', since in
C one still cannot return array values.

So that is why time(3), gmtime(3), localtime(3), and ctime(3) all take
their arguments as pointers rather than as values.

>    long int thetime;
>    thetime = time(NULL);
>    printf("It is now %s\n", ctime(&thetime));

Actually, a newline is not necessary here, since the buffer filled in
by `ctime' always ends with a newline.  This is because the original
implementation of the `date' program was something like:

------------------------------------
#include <stdio.h>
extern time();
extern char *ctime();

int
main()
{
	int thetime[2]

	time(thetime);
	fputs(ctime(thetime), stdout);
	return 0;
}
------------------------------------

Obviously, you wouldn't ever want to copy this in a modern program.

-GAWollman

--
Garrett A. Wollman   | Shashish is simple, it's discreet, it's brief. ... 
wollman@lcs.mit.edu  | Shashish is the bonding of hearts in spite of distance.
Opinions not those of| It is a bond more powerful than absence.  We like people
MIT, LCS, ANA, or NSA| who like Shashish.  - Claude McKenzie + Florent Vollant



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