Date: Tue, 23 Sep 2025 09:42:31 -0700
From: Paul Eggert via tz <[email protected]>
Message-ID: <[email protected]>
| A first review found a problem: the FreeBSD implementation does not
| conform to the C standard or to POSIX. These standards require that
| successful calls to localtime and gmtime must always return the same
| pointer;
They do nothing of the kind. They allow implementations to return
the same data structure (a pointer to ...) they certainly do not
require it.
| see, for example:
| https://pubs.opengroup.org/onlinepubs/9799919799/functions/gmtime.html
Yes, let's read that:
| It says, "The asctime(), ctime(), gmtime(), and localtime() functions
| shall return values in one of two static objects: a broken-down time
| structure and an array of type char.
That just requires that the implementation provide storage, and by being
static, storage that does not need to be (and cannot be) freed by the
application. The "one of two" is just that some return a pointer to
a struct tm, and others to a char [].
But this next sentence is where it matters:
| Execution of any of the functions
| that return a pointer to one of these object types may overwrite the
| information in any object of the same type pointed to by the value
| returned from any previous call to any of them."
Notice "may overwrite" not "shall overwrite" which it would need to be
to require that there only be one struct tm for all of the functions which
return a pointer to that, and one char[] for all the functions which return
char *.
The implementation is permitted to have all the tm returning functions
use the same one, or all in the same thread use the same one, or all calls
of the same function name use the same one, but different functions use
a different one, or that, with different copies in different threads, or
just about anything else it desires - just as long as it doesn't malloc()
storage for the results (which would require a free() in the application).
| FreeBSD doesn't do that: it returns a pointer to thread-local storage.
That's perfectly fine.
| Is it intended that FreeBSD not conform to POSIX and C here?
On that issue at least (I didn't look at the rest of the code), it does.
| I suppose the idea was that poorly-written unportable programs that use
| localtime in multiple threads are more likely to behave as their
| misguided authors intended.
Probably, and I agree, such an application would not be portable,
perhaps not conforming either, but that's not on the implementation.
| Still, it seems clear there is a conformance issue here.
Not in the implementation.
| I suspect that when the 2009 change was put in, its
| reviewers didn't know about the conformance bug.
Hardly surprising, as there isn't one.
The supposed test program is nonsense, both the reported results from
Fedora, and FreeBSD, are conforming.
kre