Making C's time interfaces describe their constraints
N2402 proposes caller-owned conversion buffers and more explicit clock semantics, using existing C syntax to make interface requirements visible.
A function declaration can hide the minimum storage its argument must provide. C's time interfaces contain several examples, alongside shared conversion buffers and unclear relationships between clocks. Jens Gustedt's N2402 proposal, listed on July 7 in the WG14 document log, treats these as related interface problems. Its approach combines POSIX-style functions with constraints expressed in C's existing array-parameter syntax.
C remains important to me as a language for interoperation. That makes library declarations particularly interesting. A declaration is often the first description available to a caller in another language, yet a pointer parameter alone says little about the storage or synchronization policy behind it.
Putting minimum bounds in declarations
N2402 illustrates its approach by rewriting the declaration of mktime. The proposed spelling communicates that its argument must give access to at least one structure:
time_t mktime(struct tm timeptr[static 1]);
This is proposed standard-library wording, not a new array object passed by value. The C11 committee draft already specifies adjustment of an array parameter to a pointer parameter. The static bound adds a call requirement. It lets a compiler associate the declaration with a minimum accessible extent.
A plain pointer declaration and this spelling therefore need not have different calling conventions. The change gives analysis more information about a contract that already exists in prose. The proposal exempts time from this treatment because that function explicitly permits a null pointer argument. Applying a minimum-one-element rule indiscriminately would change that valid use.
The same technique can express the minimum buffer for a proposed reentrant text conversion. A known bound is more useful at the parameter declaration than an assumption left to be rediscovered at each call site. It cannot make every invalid call statically detectable, but it provides information when the compiler does know the object size.
Returning results into caller storage
The existing conversion functions can return pointers into static storage. That creates lifetime and concurrency questions separate from whether their output format is correct. Saving a returned pointer does not give the caller an independent result object. A subsequent conversion can affect the storage to which it points.
The proposal adds functions with an _r suffix and caller-supplied storage. It includes localtime_r and gmtime_r for broken-down time, along with text-producing conversions. The intended requirement is that these interfaces be reentrant and free of data races. Each caller supplies the object that receives its result.
That choice makes ownership of the output visible. A thread can retain its own broken-down time without first copying a shared library result. The caller also determines when that storage stops being valid. Moving output storage into an argument addresses a specific source of shared state, while other requirements of the conversion still need specification.
I prefer that ownership model to a pointer whose usable lifetime depends on the next call into the library. It fits C's existing way of expressing storage responsibility. A caller can see the object that holds the result and the scope in which it exists.
A fixed format still needs bounds
The paper examines asctime's fixed text representation. It proposes limiting writes to the known buffer size and replacing undefined behavior for certain invalid time fields with unspecified output contents. This distinguishes two separate promises, whether the output is a useful date and whether producing it stays within storage.
That distinction matters when a malformed value reaches formatting code. A caller may have a valid output buffer while the fields supplied for conversion do not describe a normal time. Requiring bounded writes gives the library a meaningful constraint even when it cannot supply meaningful calendar text.
N2402 also notes a composition problem in ctime. Its definition uses localtime followed by asctime, yet failure in the first operation can produce an argument that the second does not accept. A compact functional equivalence does not automatically describe an error policy. The proposal asks the committee how explicitly that policy should appear.
Clock identity is different from resolution
The time-base proposals address another hidden assumption. An application measuring an interval needs to know whether changing system time can affect the readings. An application producing calendar timestamps needs an agreed reference. Those uses cannot be explained solely by the number of digits in a timespec.
N2402 proposes optional named bases for elapsed time and CPU time, adapting POSIX distinctions. It also proposes timespec_getres so a caller can query resolution. A fine-grained representation is not itself a guarantee that the underlying clock changes at that granularity. Querying resolution gives a program a separate fact.
These additions remain proposals for C2x. Their common purpose is to make independent requirements explicit, including output storage and the behavior of a selected time base. That separation helps a caller choose a conversion or measurement according to its actual contract, including which object receives the result and which clock changes can affect an interval.