Unnamed parameters make ignored callback arguments explicit
N2510 removes the requirement to name every parameter in a C function definition. Callback implementations can retain the required signature without introducing an unused identifier.
A callback interface can require an argument that a particular implementation has no reason to inspect. The argument belongs to the interface, even when its name has no useful role inside the function body. Aaron Ballman's N2510, dated April 9, proposes allowing such parameters to remain unnamed in C function definitions. The paper appears in the WG14 document log.
The distinction is small but useful. Removing an argument would change the interface. Omitting its local identifier preserves the parameter while stating that the function does not access it by name. I value that kind of change in C because it lets the source express an existing interface decision with less incidental code.
The interface still has the parameter
N2510 identifies an inconsistency in C17. Function declarations can omit parameter names, but definitions must supply them. Its proposed change extends the permission to definitions. The paper also records consensus from a straw poll on the preceding revision, with N2510 supplying the requested wording adjustment.
Consider a callback whose interface supplies an application context pointer. A general callback type can support implementations that need this pointer and implementations that do not. The callback's caller must use the agreed signature in either case.
The following illustrative definition uses the proposed syntax. It is a proposal example, not a claim that this is portable C17.
int accept_event(int event, void *)
{
return event != 0;
}
The second parameter remains a pointer parameter. A call to this function still supplies the corresponding argument, and a function-pointer declaration still includes its type. Nothing in the omission says that the caller should change how it invokes the callback.
This distinction matters when reading unfamiliar code. An unnamed parameter conveys a fact about the implementation's use of an interface. It does not convey that the parameter is optional for the caller. A callback registration system can remain general while each callback body makes its own needs explicit.
Why a name can be misleading
Under the existing rule, an implementation supplies a name even when it intends never to use the value. The source may then include an explicit expression to suppress an unused-parameter diagnostic. N2510 illustrates the conventional (void)arg treatment and contrasts it with omitting the name.
That expression is understandable, but it describes a diagnostic convention in the function body. The actual design decision occurred in the definition's parameter list. Moving the expression of intent to that list reduces the amount of explanation the body needs.
A name can also imply that the body has a meaningful role for the argument. Calling it unused addresses that implication through a naming convention. Omitting it gives the compiler the same information directly, without requiring a project to reserve a special identifier pattern.
There is a tradeoff for readers. A descriptive parameter name can explain the meaning of an interface even when the implementation ignores the value. That information can remain in the public declaration or accompanying interface documentation. The proposed permission does not require authors to remove useful names from every definition.
A change for shared language boundaries
The paper identifies mixed C and C++ code as a motivation. C++ already allows the omission in a definition, so a source construct can produce different diagnostics when compiled in the two language modes. Aligning the rule reduces one such difference without changing the callback's type.
For a header containing function definitions, the practical benefit is that one spelling can describe the unused parameter in both contexts. This follows from aligning the permission, although it does not make every other construct in that header valid in both languages. Shared source still needs to respect each language's remaining rules.
C's importance to me includes the interfaces through which other languages call it. This proposal addresses a smaller boundary within that wider subject. The calling interface can stay stable while the source stops requiring an implementation detail that has no useful name.
The proposal also considers interaction with older function-definition syntax. Its analysis concludes that the typedef ambiguity it examines already has an answer under the existing rules. That is a relevant constraint on a small language change. Removing one requirement should not silently change how a different existing construct is parsed.
What the body can claim
An unnamed pointer argument does not establish that the caller passed no context. It says that this body has no parameter identifier through which to refer to it. The difference is useful in an interface review because a caller may still evaluate an expression to produce the supplied argument.
That means an application should reason separately about producing an argument and consuming it. Omitting the receiving name does not authorize deleting caller-side work with effects. The proposal changes a definition's declaration requirements, so broader behavioral claims need their own justification.
For callback implementations, the resulting source can retain the interface's complete type while showing which values the body actually names. N2510 places that choice where a reader first encounters the implementation's parameters, and leaves descriptive names available wherever they continue to explain the code.