Linux Hardening
 help / color / mirror / Atom feed
From: Alejandro Colomar <alx@kernel.org>
To: Martin Uecker <uecker@tugraz.at>,
	 Christopher Bazley <chris.bazley.wg14@gmail.com>,
	Alex Celeste <alexg.nvfp@gmail.com>,
	 Joseph Myers <josmyers@redhat.com>,
	Aaron Ballman <aaron@aaronballman.com>
Cc: Douglas McIlroy <douglas.mcilroy@dartmouth.edu>,
	 Bruno Haible <bruno@clisp.org>, Paul Eggert <eggert@cs.ucla.edu>,
	 Florian Weimer <fweimer@redhat.com>,
	Jonathan Corbet <corbet@lwn.net>, Kees Cook <kees@kernel.org>,
	 Eric Biggers <ebiggers@kernel.org>,
	Ard Biesheuvel <ardb@kernel.org>,
	 Daniel Thompson <danielt@kernel.org>,
	Daniel Lundin <daniel.lundin.mail@gmail.com>,
	 "Valentin V. Bartenev" <vbartenev@gmail.com>,
	Andrew Clayton <andrew@digital-domain.net>,
	 "Brian W. Kernighan" <bwk@cs.princeton.edu>,
	"G. Branden Robinson" <branden@debian.org>,
	 "Basil L. Contovounesios" <basil@contovou.net>,
	"Jason A. Donenfeld" <jason@zx2c4.com>,
	 Linus Torvalds <torvalds@linux-foundation.org>,
	onf <onf@disroot.org>, Rich Felker <dalias@libc.org>,
	 linux-hardening@vger.kernel.org,
	Alejandro Colomar <alx@kernel.org>
Subject: [RFC v3 1/6] alx-0077r3 - disallow function parameters of function type
Date: Mon, 26 Jan 2026 13:48:22 +0100	[thread overview]
Message-ID: <aXdijei6-wLu4IUB@devuan> (raw)
In-Reply-To: <aXdhh1r7ePA5SrIE@devuan>

[-- Attachment #1: Type: text/plain, Size: 5442 bytes --]

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 <alx@kernel.org>
	Alex Celeste <alexg.nvfp@gmail.com>

	Cc: Martin Uecker <uecker@tugraz.at>
	Acked-by: Bruno Haible <bruno@clisp.org>
	Acked-by: Doug McIlroy
	Acked-by: Andrew Clayton <ac@sigsegv.uk>

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>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

  reply	other threads:[~2026-01-26 12:48 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <aXZM5O2mU2e3LJBJ@devuan>
2026-01-26 12:48 ` [RFC v3 0/6] Improve function parameters in ISO C2y Alejandro Colomar
2026-01-26 12:48   ` Alejandro Colomar [this message]
2026-01-26 12:48   ` [RFC v3 2/6] alx-0076r3 - incompatible array parameters Alejandro Colomar
2026-01-26 12:48   ` [RFC v3 3/6] alx-0078r2 - [static n] shouldn't access more than n elements Alejandro Colomar
2026-01-28  9:54     ` Daniel Thompson
2026-01-28 15:14       ` Alejandro Colomar
2026-01-26 12:49   ` [RFC v3 4/6] alx-0079r2 - [static n] == non-null [n] Alejandro Colomar
2026-01-26 12:49   ` [RFC v3 5/6] alx-0081r2 - array parameters of 0 elements Alejandro Colomar
2026-01-28 10:14     ` Daniel Thompson
2026-01-28 15:21       ` Alejandro Colomar
2026-01-26 12:49   ` [RFC v3 6/6] alx-0080r1 - [static] without array length expression Alejandro Colomar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aXdijei6-wLu4IUB@devuan \
    --to=alx@kernel.org \
    --cc=aaron@aaronballman.com \
    --cc=alexg.nvfp@gmail.com \
    --cc=andrew@digital-domain.net \
    --cc=ardb@kernel.org \
    --cc=basil@contovou.net \
    --cc=branden@debian.org \
    --cc=bruno@clisp.org \
    --cc=bwk@cs.princeton.edu \
    --cc=chris.bazley.wg14@gmail.com \
    --cc=corbet@lwn.net \
    --cc=dalias@libc.org \
    --cc=daniel.lundin.mail@gmail.com \
    --cc=danielt@kernel.org \
    --cc=douglas.mcilroy@dartmouth.edu \
    --cc=ebiggers@kernel.org \
    --cc=eggert@cs.ucla.edu \
    --cc=fweimer@redhat.com \
    --cc=jason@zx2c4.com \
    --cc=josmyers@redhat.com \
    --cc=kees@kernel.org \
    --cc=linux-hardening@vger.kernel.org \
    --cc=onf@disroot.org \
    --cc=torvalds@linux-foundation.org \
    --cc=uecker@tugraz.at \
    --cc=vbartenev@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox