There are at least 3 diff places where the behavior of the time()
function is documented.
The ISO C standard says:
The time
function returns the implementation’s best approximation to
the current calendar time. The value (time_t)(-1)
is returned if the
calendar time is not available. If timer
is not a null pointer, the
return value is also assigned to the object it points to.
Other wording in the standard makes it clear that passing an invalid argument (which is what you're doing) has undefined behavior. time()
is required to handle null pointers, but not invalid ones.
POSIX says:
Upon successful completion, time() shall return the value of time.
Otherwise, (time_t
)-1 shall be returned.
which doesn't allow for a result other than the current time or (time_t)(-1)
. On the other hand, POSIX also says:
The functionality described on this reference page is aligned with the
ISO C standard. Any conflict between the requirements described here
and the ISO C standard is unintentional. This volume of POSIX.1-2008
defers to the ISO C standard.
which could be taken to imply that the behavior of time()
with an invalid argument is undefined, as it is in C.
The Linux man page says:
On success, the value of time in seconds since the Epoch is returned.
On error, ((time_t) -1) is returned, and errno is set appropriately.
It also explicitly says that errno
is set to EFAULT
if "t
points outside your accessible address space". So it defines the behavior in a case where the behavior is left undefined by the standard, and that's a perfectly valid thing for an implementation to do.
The weird thing is that it returns -14
(-EFAULT
) rather than setting errno
to EFAULT
. Returning a negated errno
value is a common convention for functions inside the Linux kernel. The wrapper in the C runtime normally negates that return value and uses it to set errno
, setting the return value to -1
(or whatever the defined error value is for the particular function). That's what I'd expect to happen here.
Another weird thing: On my system (Linux Mint 17, x86_64), calling time()
with an invalid pointer as you did causes my program to die with a segmentation fault.
I suspect a bug on your system (with a particularly easy workaround: Don't Do That).
UPDATE : Another possibility occurs to me. Your printf
calls are incorrect, or at least non-portable. You're printing time_t
values with a "%lld"
format, which requires an argument of type long long
. You should cast the argument to long long
:
printf("Number of seconds since the Epoch: %lld\n",
(long long)secs);
printf("It should return ((time_t) -1) on error: %lld\n",
(long long)((time_t) -1));
If time_t
and long long
are the same widths on your system, it will probably work without the casts (but you should add them anyway). But if time_t
is narrower than long long
, printf
could be picking up the stray -14
value from adjacent memory.
What are the sizes of time_t
and long long
on your system? Does casting the arguments change the behavior?