August 21, 2026·5 min read·engineeringcc2ystandardscontracts

The interface problems on the Ottawa C agenda

WG14 met in Ottawa to continue C2y work. The meeting papers show how apparently small library interfaces expose difficult questions about types and error behavior.

Computing the smaller of two integers should be a modest library task. In C, the interface must account for signed and unsigned operands, promotions and accidental repeated evaluation. That problem appears alongside much larger language proposals in the papers prepared for the WG14 meeting in Ottawa. The committee meeting record places the meeting on August 17 through 21, and its preliminary agenda shows work on C2y and separate technical specifications.

The useful connection between these papers is their attempt to make familiar interfaces express what programmers need. A minimum operation needs a numerical answer despite mixed types. A string-copying interface needs a statement of which inputs are valid and what failure means. Both problems become harder when the specification must also accommodate existing code and the language rules already used to express it.

C was my first language, and its interoperation role still matters to me after thirty years. That makes interface work especially interesting. An interface can remain short while carrying obligations that occupy many paragraphs of the standard. Small declarations deserve careful language design because their meaning travels into code written by people who never read the proposal that produced them.

Minimum has a type-selection problem

Jens Gustedt discusses the integer problem in N3868, type-safe minimum and maximum macros. A naive macro can evaluate one argument more than once. A direct comparison between mixed signed and unsigned values can also produce a result inconsistent with their numerical ordering. Avoiding repeated evaluation does not by itself solve the type-conversion problem.

The paper proposes stdc_min and stdc_max in <stdint.h>. They apply integer promotions and compute a numerically exact result. For maximum, the result type is the common real type after the usual arithmetic conversions. For minimum, when the promoted operands differ in signedness, the result type is the signed operand type. When both have the same signedness, minimum uses the common real type.

The reasoning for the mixed minimum case is direct. A negative signed operand is necessarily less than an unsigned operand. If the signed operand is nonnegative and the unsigned operand is smaller, that unsigned value also fits within the signed operand range. The selected signed type can therefore represent the minimum without changing the numerical answer. This is a property of the operation, not a general rule that mixing integer types is harmless.

The corresponding maximum result can use the common real type. A negative signed operand cannot be the maximum against an unsigned value. When the signed operand is nonnegative, converting it for the selected result does not require preserving a negative value. The proposal uses separate type rules because the two operations have different representability arguments.

Earlier revisions also tried to preserve integer-constant-expression status when the inputs were integer constant expressions. N3868 drops that claim after it attracted less support than the basic operation. This is a concrete example of reducing a proposal to the part with stronger agreement. A reliable numerical minimum can still be useful without promising every compile-time use that an earlier design considered.

The preliminary agenda records an earlier online poll supporting N3868 and an action for the editor to integrate it. That is a specific status recorded before the Ottawa meeting. Other papers on the agenda remain proposals, so their appearance there does not establish adoption or implementation availability.

Contracts put library requirements in declarations

Another prepared paper, N3930, interfaces with contracts alongside Annex K, approaches familiar library operations through preconditions and postconditions. Gustedt describes the limited implementation and use of Annex K after disputes over its design. The proposal attempts to reuse work identifying erroneous calls while expressing those conditions in alternative declarations.

The design puts array lengths before the arrays they describe. It expresses input requirements with _Pre and output properties with _Post. These spellings belong to the proposal and its associated contracts work. They are not facilities that an ordinary C23 compiler is required to accept. The paper presents them as a way to examine whether a richer declaration can carry the constraints currently described elsewhere.

String copying provides a detailed example. The proposed stdc_strcpy checks that the source string fits within the destination bound, that the relevant source and destination regions do not overlap, and that the returned destination is terminated. It also specifies that the returned pointer equals the destination pointer. These conditions describe different parts of the operation, including a requirement on the caller and a result the implementation must deliver.

The paper introduces helper predicates for checking byte ranges and bounded string lengths. That is necessary because a contract needs expressions capable of describing the property it checks. A declaration saying that regions do not overlap is only useful if the language and library can express the relevant regions with defined behavior. The proposal includes implementation sketches, which make those dependencies visible.

Its treatment of strncpy also preserves the distinction between a bounded copy and guaranteed string termination. The proposed operation follows the existing function behavior of padding trailing bytes with zeroes. Its termination condition depends on whether padding occurs. Replacing that behavior with a general claim that bounded copying always produces a string would misdescribe the interface the paper actually explores.

The agenda spans different stages of standardization

Ottawa work includes the defer and nullability technical specifications as well as the main C2y draft. The preliminary agenda also schedules C23 issue-log discussion. Those categories represent different kinds of work. Clarifying an existing rule and designing a new interface can both occupy committee time, but they produce different evidence for someone choosing a compiler or library API.

I value the attention these papers give to precise boundaries. The minimum proposal derives a result type from the operation it performs, and the contracts paper makes individual library obligations inspectable. Neither requires describing C as uniformly safe or unsafe. The practical information lies in which conversion preserves a value and which condition an interface can actually express.

As the Ottawa meeting concludes, the prepared papers provide concrete designs to examine alongside the continuing C2y text. N3868 includes a narrowed revision history and a numerical argument for its type rules. N3930 supplies library declarations detailed enough to expose unresolved dependencies on contracts and helper predicates. Those are useful inputs for implementation experiments without assuming that a place on the meeting agenda makes every proposed declaration part of the language.