Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does time(time_t *) function both return and set the by-ref?

Tags:

c

time

libc

I've always been curious, why does the time(time_t *) function both return a time_t, and set the time to the passed in pointer?

Example of returning the time:

time_t myTime = time(NULL);
printf("The time is now %s", ctime(&myTime));

Example of setting the value to the pointer:

time_t myTime;
time(&myTime);
printf("The time is now %s", ctime(&myTime));

I originally thought there would be a performance gain by writing to the memory instead of returning, but if it has to do both, doesn't that just make it slower?

like image 964
wjl Avatar asked Mar 30 '12 14:03

wjl


People also ask

What does time_t return in C?

The C library function time_t time(time_t *seconds) returns the time since the Epoch (00:00:00 UTC, January 1, 1970), measured in seconds. If seconds is not NULL, the return value is also stored in variable seconds.

What type of value is returned by the time () function?

Returns the decimal number for a particular time. If the cell format was General before the function was entered, the result is formatted as a date. The decimal number returned by TIME is a value ranging from 0 (zero) to 0.99988426, representing the times from 0:00:00 (12:00:00 AM) to 23:59:59 (11:59:59 P.M.).

How does time () function work in C?

The time() function is defined in time. h (ctime in C++) header file. This function returns the time since 00:00:00 UTC, January 1, 1970 (Unix timestamp) in seconds. If second is not a null pointer, the returned value is also stored in the object pointed to by second.

What does time null return?

time(NULL) returns the number of seconds elapsed since 00:00:00 hours, GMT (Greenwich Mean Time), January 1, 1970.


2 Answers

There's no real benefit in the way it's currently defined.

I suspect that when the time() function was first defined, it used a type that could not be returned from a function. Very early C implementations didn't have long int and were not able to return structures from functions. On a system with 16-bit ints, the only way to represent a time would be as a structure or as an array; 16 bits worth of seconds is less than a day.

UPDATE: My speculation is confirmed, see below.

So early implementations of time() might have been used something like this (speculation):

time_t now;
time(&now);    /* sets now.time_high, now.time_low */

or perhaps:

int now[2];
time_t(now);    /* sets now[0], now[1] */

When later C implementations added longer integers and the ability to return structures by value, the ability to return a time_t value from the time() function was added, but the old functionality was kept to avoid breaking existing code.

I think that if time() were being defined today, it would look more like this:

time_t time(void);

I haven't been able to confirm that old implementations of the time() function worked this way (try Googling "time"!), but it makes sense given the history of the language.

If you pass a null pointer to the time() function, it returns the current time without also storing it in a variable; this avoids some of the performance penalty:

time_t now = time(NULL);

UPDATE

Early UNIX sources are available in https://github.com/dspinellis/unix-history-repo

Checking out the Research-V6 git tag, the man page for the time() system call is in usr/doc/man/man2/time.2. It's written in an obsolete form of *roff, but here's my attempt at formatting it. (The implementation, written in PDP-11 assembly and callable from C, is in usr/source/s2/time.s.)

C didn't have void functions at that time. Functions without a declared return type would return int by default. It's not clear to me what the time function would return, but my guess is that it would be the high-order 16-bit word of the 32-bit value. As of the date on the man page, that would have been about 1730, in units of 216 seconds (18h12m16s). Correctly written C code would not have attempted to use the return value.

TIME 8/5/73

NAME

time - get date and time

SYNOPSIS

(time = 13.)
sys time

time(tvec)
int tvec[2]

DESCRIPTION

Time returns returns the time since 00:00:00 GMT, Jan. 1, 1970, measured in seconds. From as, the high order word is in the r0 register and the low order is in r1. From C, the user-supplied vector is filled in.

SEE ALSO

date (I), stime (II), ctime (III)

like image 114
Keith Thompson Avatar answered Oct 18 '22 22:10

Keith Thompson


It allows you to nest a call to time() within another expression, instead of doing it in a separate statement:

time_t x = time(&now) + more_time;

When the above statement finishes, now should contain the current time, and x should contain the current time plus some value.

strcpy falls in the same case because it returns the same char * pointer that has been passed as its destination, so nesting it is possible as well:

printf("Copied string is %s", strcpy(dst, src));
like image 20
Blagovest Buyukliev Avatar answered Oct 18 '22 23:10

Blagovest Buyukliev