[This answer is adapted from a very similar answer to a slightly different question.]
std::time()
has an "extra argument" because it's the same as C's time()
function, which is very, very old. It goes back to the dawn of C, when the language didn't even have type long
. Once upon a time, the only way to get something like a 32-bit type was to use an array of two int
s — and that was when int
s were 16 bits.
So you called
int now[2];
time(now);
and time
filled the 32-bit time into now[0]
and now[1]
, 16 bits at a time. If you wanted to print the time in human-readable format, you called ctime(int *)
, which also accepted the time as a pointer, for basically the same reason.
Later on, dmr finished adding long
to the compiler, so you could start saying
long now;
time(&now);
At about the same time, someone realized it'd be useful if time()
went ahead and returned the value, now that it could, rather than just filling it in via a pointer. But — backwards compatibility is a wonderful thing — for the benefit of all the code that was still doing time(&now)
, the time()
function had to keep supporting the pointer argument. Which is why — and this is why backwards compatibility is not always such a wonderful thing, after all — if you were using the return value, you still had to pass NULL as a pointer:
long now = time(NULL);
Later still, we started using time_t
instead of plain long
for times, so that, for example, it can be changed to a 64-bit type, dodging the y2.038k problem.
So, in summary, the "extra argument" is a historical relic, left over from a time when it was impossible for time()
to simply return the time, because there was no suitable return type. Moreover, the extra argument had to be a pointer, to a data structure to be filled in, because that data structure — an array — couldn't be simply returned by a function, either.