Name
alx-0077r3 - disallow function parameters of function type
Principles
- Uphold the character of the language.
- Avoid quiet changes.
And from previous charters:
C23:
- APIs should be self-documenting when possible.
Category
Language; function parameters.
Authors
Alejandro Colomar <[email protected]>
Alex Celeste <[email protected]>
Cc: Martin Uecker <[email protected]>
Acked-by: Bruno Haible <[email protected]>
Acked-by: Doug McIlroy
Acked-by: Andrew Clayton <[email protected]>
History
<https://www.alejandro-colomar.es/src/alx/alx/std/wg14/alx-0077.git/>
r0 (2026-01-24):
- Initial draft.
r1 (2026-01-25):
- Re-title.
r2 (2026-01-25):
- Acked-by Bruno.
- Add Comments section.
r3 (2026-01-26):
- Acked-by.
- Tweak the constraint in p3 instead of adding a new one.
- Co-authored-by Alex Celeste.
- ffix
- Add Celeste's comment about the C89/C90 rationale and K&R.
Abstract
A function parameter of function type is adjusted to a pointer:
void f(void fp(void));
is adjusted to
void f(void (*fp)(void));
This is unnecessary and confusing; let's disallow it.
Discussion
I've never seen any code written declaring a function parameter
of function type. Unlike array parameters, this adjustment
seems to be seldom used, if at all.
We can turn this into a constraint violation, which will
require that the few users of this quirk of C to tweak their
declarations to declare a pointer type (which is what these
parameters have always been).
I've tried finding such uses with a search engine, but didn't
find anything; it could be that there are no uses, or it could
be that it's hard to write a regex that would find this. FWIW,
the standard has one example, just to document this weird
allowance, and uses the usual pointer to function syntax
elsewhere.
Apart from resulting in more explicit code, this simplifies the
wording, which would get more complex with other proposals that
will modify compatibility rules regarding adjustment (it would
require specifying some exceptions).
Comments
On 2026-01-25T19:48:04+0100, Bruno Haible wrote:
> I saw such a function parameter of function type once in 25 years of
> C programming, and I found it confusing.
>
> This is an incompatible change to the language. But the impact on
> existing code is so small that it's worth it.
---
On 2026-01-25T18:19:02-0500, Douglas McIlroy wrote:
> All six proposals look eminently reasonable. They simplify
> the language and remove surprises. I suspect these proposals
> will invalidate very few existing programs. In any event, the
> required corrections will improve the legibility and
> maintainability of such programs.
>
> Doug McIlroy
---
On 2026-01-26T02:27:02+0000, Alex Celeste wrote:
> I was surprised not to find any comment in the C90 Rationale
> about this.
>
> KnR1 says that 'since a reference to an array in any context
> (in particular as an actual parameter) is taken to mean a
> pointer to the first element of the array, declarations of
> formal parameters declared ‘‘array of...’’ are adjusted to
> read ‘‘pointer to ...’’.' There's no mention of functions in
> this part, even though the KnR1 language does explicitly
> describe using "bare" function identifiers to decay to
> function pointers.
>
> This honestly feels like something that was added for
> stylistic consistency. Function pointers were already
> well-developed before this became a language feature.
> Combined with the fact that you _can't_ use a function type in
> a definition of a thing with that type, and using it in an
> external declaration creates something incompatible with an
> object of function pointer type, and I think this was an
> attempt at consistency that ended up creating an inconsistency
> instead.
> The [...] example does look unintentional to me for that
> reason.
Proposed wording
Based on N3685.
6.7.7.4 Function declarators
@@ Constraints, p3
After adjustment,
the parameters in a parameter type list
in a function declarator
that is part of a definition of that function
-shall not have incomplete type.
+shall have complete object type.
@@ Semantics, p8
-A declaration of a parameter
-as "function returning type"
-shall be adjusted
-to "pointer to function returning type",
-as in 6.3.3.1.
@@ p15
In the determination
of type compatibility and of a composite type,
each parameter declared with
-function or array type
+array type
is taken as having the adjusted type
and each parameter declared with qualified type
is taken as having the unqualified version of its declared type.
6.9.2 Function definitions
@@ Semantics, p15
EXAMPLE 2 To pass one function to another, one can say
int f(void);
/* ... */
- g(f);
+ g(f); /* or g(&f); */
Then the definition of g can read
void g(int (*funcp)(void))
{
/* ... */
(*funcp)(); /* or funcp(); */
}
-or, equivalently,
- void g(int func(void))
- {
- /* ... */
- func(); /* or (*func)(); */
- }
## I added 'g(&f)' for consistency with comments that show
## alternate valid syntax; it seems an accidental omission that
## could be fixed editorially.
--
<https://www.alejandro-colomar.es>
signature.asc
Description: PGP signature
