From owner-freebsd-questions Fri Oct 27 08:22:14 1995 Return-Path: owner-questions Received: (from root@localhost) by freefall.freebsd.org (8.6.12/8.6.6) id IAA24178 for questions-outgoing; Fri, 27 Oct 1995 08:22:14 -0700 Received: from halloran-eldar.lcs.mit.edu (halloran-eldar.lcs.mit.edu [18.26.0.159]) by freefall.freebsd.org (8.6.12/8.6.6) with SMTP id IAA24164 for ; Fri, 27 Oct 1995 08:22:10 -0700 Received: by halloran-eldar.lcs.mit.edu; (5.65/1.1.8.2/19Aug95-0530PM) id AA22958; Fri, 27 Oct 1995 11:22:05 -0400 Date: Fri, 27 Oct 1995 11:22:05 -0400 From: "Garrett A. Wollman" Message-Id: <9510271522.AA22958@halloran-eldar.lcs.mit.edu> To: Dave Andersen Cc: freebsd-questions@freebsd.org Subject: Re: Help -- Stupid "C" question. In-Reply-To: <199510270354.VAA27065@terra.aros.net> References: <199510270354.VAA27065@terra.aros.net> Sender: owner-questions@freebsd.org Precedence: bulk Hey, it's portable programming time! < 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 ?) 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 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