June 27, 2023·4 min read·engineeringcc23standards

C23 ballot review returns to the meaning of declarations

June's second committee-draft review puts declaration terminology and compatible types alongside unresolved questions about undefined behavior.

A language standard has to specify which identifiers a declaration actually declares. That sounds administrative until a declaration contains another declaration, a type definition, or an initializer with its own names. C23's June review includes papers that address exactly those boundaries. The work matters because a rule expressed in terms of declared identifiers can otherwise apply to more names than its author intended.

The WG14 meeting record lists the virtual June meeting. Its corrected agenda, N3137, identifies the purpose as resolving the second committee-draft ballot for C23. It schedules June 20 through 23, with June 26 and 27 reserved if needed. The distinction between scheduled sessions and a published language release remains important.

I value C's small grammar, but a small grammar does not remove the need for precise terminology. Nested declarations are a good example. The same short stretch of source can introduce names under different rules, and a specification needs to identify which of those names a particular requirement concerns.

A declaration contains several possible naming events

Martin Uecker's N3123, dated April 22, proposes clarification of declaration contexts. Its central terminology change distinguishes identifiers declared by an init-declarator list from additional identifiers introduced inside nested declarations or type specifiers. That gives later requirements a narrower subject.

The paper also revisits restrictions on underspecified declarations, including declarations using type inference. It explicitly identifies only one of its changes as intended to alter semantics. That separation helps a reader distinguish a repair to the document's vocabulary from a proposal to accept additional programs.

The engineering consequence is that a new feature needs rules for the declarations surrounding its obvious examples. An inferred object can have an initializer that contains other constructs. A restriction intended for the inferred object's identifier should not accidentally become a restriction on every name appearing within that initializer.

A clarification also needs to account for declarations that exist without ordinary object declarators. Structure tags and enumeration constants are familiar examples of names introduced through type-related syntax. Treating every declaration as though it were a simple object definition would leave those cases inadequately described.

Compatible types need a composite result

Uecker's N3122, also dated April 22, examines composite types for structures and unions. It identifies a missing explicit rule relevant to repeated declarations and to the conditional operator. The proposed treatment forms the composite recursively through the members.

The paper distinguishes a composite type from the question of whether it is the same type as one of its inputs. It also offers alternatives involving enumerations and records disagreement among implementations. These are proposed resolutions to specification questions, not a claim that every compiler already agrees.

This matters whenever two declarations need to describe one program entity consistently. Compatibility establishes a relationship between the types, but the language also needs to say which type information applies after they are combined. A conditional expression raises a related question because its alternatives must lead to a specified result type.

For me, that is part of C's practical value as an interface language. Declarations supplied by different parts of a program have to agree in a way that compilers can describe consistently. A source-level rule about composite types can therefore matter even when no structure's physical representation is being redesigned.

Undefined behavior remains a separate question

The agenda also includes Uecker's N3128, dated May 5. It argues for a concrete interpretation of undefined behavior that preserves preceding observable behavior. Its concern is whether a later erroneous operation can invalidate reasoning about earlier I/O or volatile accesses.

The paper presents this as a proposal for clarification. It should not be read as a new guarantee already available to application code. Its discussion connects the proposed interpretation to partial correctness and to optimization, including the treatment of operations around function calls.

That distinction between argument and adopted rule is particularly important here. A programmer may find the proposed guarantee desirable without being able to rely on it in an existing compiler. The useful contribution of the paper is to state the desired relationship between an erroneous operation and behavior that precedes it.

The subject also differs from making every operation defined. Preserving earlier observable behavior would not supply a useful numeric result for an invalid arithmetic operation. It concerns how far the consequences extend through the execution. Those are different promises, and a standards discussion needs to keep them separate.

The agenda distinguishes editorial work from technical decisions

June's review plan groups ordinary editorial comments for collective acceptance, while moving several comments marked editorial into technical discussion. It also calls out floating-point responses that need special handling. The classification determines which changes can be processed together and which require individual consideration.

This is a practical consequence of reviewing a mature draft. A wording correction can change an implementation's obligations if it changes the set of declarations covered by a requirement. Labels such as editorial are useful for organizing the work, but the content of the change still determines whether it affects programs.

The agenda separately reports a procedural disagreement over Technical Specifications that extend standards. It says ISO's central secretariat has rejected that use and that the convenor is working with the SC22 committee manager on the issue. The disposition of TS 6010 remains unresolved in that report.

That procedural issue should not be confused with the C23 ballot itself. The agenda treats the committee-draft review and the Technical Specification problem separately. A reader can therefore understand the June work without assuming that every related document has the same publication status.

The significance of this meeting lies in making the draft's obligations more exact. Declaration contexts determine which identifiers a restriction covers. Composite types determine how compatible declarations combine. The undefined-behavior paper asks a broader execution question whose status remains a proposal. Those distinctions give implementers and programmers a clearer account of what the public papers say at this stage of C23 review.