* Re: [PATCH] man/: SYNOPSIS: Remove GNU forward-declarations of parameters for lengths of array parameters
2026-10-22 16:44 [PATCH] man/: SYNOPSIS: Remove GNU forward-declarations of parameters for lengths of array parameters Alejandro Colomar
@ 2026-10-22 17:11 ` Martin Uecker
2026-10-22 20:01 ` Alejandro Colomar
2026-10-22 17:37 ` Christopher Bazley
` (2 subsequent siblings)
3 siblings, 1 reply; 27+ messages in thread
From: Martin Uecker @ 2026-10-22 17:11 UTC (permalink / raw)
To: Alejandro Colomar, linux-man
Cc: Alejandro Colomar, Michael Kerrisk, Christopher Bazley, Sam James,
Carlos O'Donell, Joseph S. Myers
Here are my 2 cents:
The one big advantage of the forward declaration syntax is, that
if one does use it, one can get real benefits in security already
today in the forms of compiler warnings and when using object-size
sanitizer. In my opinion, it is real tragedy for the world that it
is not more widely known and used (and that Clang does not want to
implement it).
On the other hand, we have now a counter proposal from Apple
which would make the simpler syntax with retrospective scoping
work. I still do not like it, as the fully developed form
would be a major pain for most C compiler to implement, but
I guess a restricted version would be ok. Unfortunately, this
syntax does not work today, so could be used in code only at
some point in the future.
Still, my recommendation would be to wait until this issue is settled
in WG14 and if Apple's proposal is accepted, use Apple's syntax
in the man pages.
Martin
*) Also I hate giving in to bullies. (not talking about
the Apple engineers)
Am Donnerstag, dem 22.10.2026 um 18:44 +0200 schrieb Alejandro Colomar:
> From: Alejandro Colomar <alx+linux-man@kernel.org>
>
> From: Alejandro Colomar <alx@kernel.org>
>
> I'm not fully convinced of this patch. But I'm open to being convinced.
> I've written the patch, as Michael asked me to do, but am willing to
> hear everyone's opinion before applying the patch.
>
> As Michael reminded me recently, and as I've defended in other cases, it
> is true that the SYNOPSIS of the manual pages does not need to be
> strictly valid C. It only needs to be useful enough for readers to
> understand the interface. Thus, if using lengths without declaring them
> would improve the usefulness of the documentation, even if becoming
> invalid C, it would be okay.
>
> However, I still have doubts, because this change comes with risks:
>
> Programmers might think it is valid C to refer to parameters that have
> not been declared yet, and use that in their code, and if they are
> unlucky, it might compile for them, which might result in UB at some
> point.
>
> One valid point is that this is rather unlikely to happen, and most of
> the time it will just result in a compiler error, because no global
> variables with the name of the parameter exist.
>
> However, with local (nested) functions, this might be easier to happen,
> as variables declared in the outer function are more likely to share a
> name with a length parameter. Given that the C Committee is working
> hard to standardize local functions, it might be a very bad idea to have
> this combination of events going on.
>
> Concerns that have been raised against using the GNU C syntax in the
> manual pages:
>
> Very very few programmers know this syntax, and thus they are confused
> when reading it for the first time.
>
> This is obviously true. However, this is true of any innovative syntax.
> We should consider whether the confusion is dangerous or not, and
> whether programmers can learn it easily or not.
>
> I believe once you've been exposed to this syntax, after some research,
> or asking the right people, one would easily learn to read it, and then
> we'd have overcome the issue. I don't think the syntax is inherently
> difficult to understand once you've seen the documentation and seen it
> a few times.
>
> Also, this syntax is not very dangerous: a programmer thinking
> that a forward declaration is actually a normal parameter will pass a
> wrong number of arguments to the function, and thus will have compiler
> errors. This syntax is quite robust, as it requires several bugs to
> happen in the same code to pass compilation silently. If one replaces
> ';' with ',', the parameter will be declared twice, which is an error.
> If one renames a forward declaration, it will not match a parameter, and
> will result in a compiler error. Only if both mistakes happen at once,
> the compilation would pass, but then the call sites would also have to
> match the bogus declaration. And also, the function definition would
> have unused parameters, which would trigger diagnostics. So, concerning
> safety, this feature is not very dangerous, even if used by someone who
> is very confused.
>
> Do we think programmers are unable to ever learn this new syntax?
> Are we ready to accept the risks of using the dangerous invalid syntax,
> but which is more intuitive to programmers?
>
> Reported-by: Michael Kerrisk <mtk.manpages@gmail.com>
> Not-yet-Signed-off-by: Alejandro Colomar <alx@kernel.org>
> ---
>
> I've cut the diff below to just a single page, because this is just for
> discussion; the actual diff is huge and uninteresting. It's just a
> removal of all uses of fwd decls of parameters in the manual pages.
>
>
> Have a lovely day!
> Alex
>
> man/man2/add_key.2 | 2 +-
> man/man2/alloc_hugepages.2 | 2 +-
> man/man2/cacheflush.2 | 2 +-
> man/man2/epoll_wait.2 | 6 +++---
> man/man2/futex_waitv.2 | 2 +-
> man/man2/get_mempolicy.2 | 2 +-
> man/man2/getdents.2 | 2 +-
> man/man2/getdomainname.2 | 4 ++--
> man/man2/getrandom.2 | 2 +-
> man/man2/getsockopt.2 | 4 ++--
> man/man2/getunwind.2 | 2 +-
> man/man2/getxattr.2 | 6 +++---
> man/man2/init_module.2 | 2 +-
> man/man2/listmount.2 | 2 +-
> man/man2/lookup_dcookie.2 | 2 +-
> man/man2/madvise.2 | 2 +-
> man/man2/mbind.2 | 2 +-
> man/man2/mincore.2 | 2 +-
> man/man2/mlock.2 | 6 +++---
> man/man2/mmap.2 | 4 ++--
> man/man2/modify_ldt.2 | 2 +-
> man/man2/mprotect.2 | 4 ++--
> man/man2/mremap.2 | 2 +-
> man/man2/msgop.2 | 4 ++--
> man/man2/msync.2 | 2 +-
> man/man2/outb.2 | 12 ++++++------
> man/man2/perfmonctl.2 | 2 +-
> man/man2/pread.2 | 4 ++--
> man/man2/query_module.2 | 2 +-
> man/man2/read.2 | 2 +-
> man/man2/readlink.2 | 4 ++--
> man/man2/recv.2 | 4 ++--
> man/man2/recvmmsg.2 | 2 +-
> man/man2/remap_file_pages.2 | 2 +-
> man/man2/s390_pci_mmio_write.2 | 4 ++--
> man/man2/send.2 | 4 ++--
> man/man2/sendmmsg.2 | 2 +-
> man/man2/setxattr.2 | 6 +++---
> man/man2/write.2 | 2 +-
> man/man2const/KEYCTL_DESCRIBE.2const | 2 +-
> man/man2const/KEYCTL_DH_COMPUTE.2const | 2 +-
> man/man2const/KEYCTL_GET_SECURITY.2const | 2 +-
> man/man2const/KEYCTL_INSTANTIATE.2const | 4 ++--
> man/man2const/KEYCTL_READ.2const | 2 +-
> man/man2const/KEYCTL_UPDATE.2const | 2 +-
> man/man2const/PR_GET_AUXV.2const | 2 +-
> man/man3/aio_suspend.3 | 2 +-
> man/man3/arc4random.3 | 2 +-
> man/man3/backtrace.3 | 6 +++---
> man/man3/bcmp.3 | 2 +-
> man/man3/bcopy.3 | 2 +-
> man/man3/bsearch.3 | 2 +-
> man/man3/bzero.3 | 2 +-
> man/man3/cfree.3 | 4 ++--
> man/man3/confstr.3 | 2 +-
> man/man3/des_crypt.3 | 4 ++--
> man/man3/explicit_bzero.3 | 2 +-
> man/man3/fgets.3 | 2 +-
> man/man3/fgetws.3 | 2 +-
> man/man3/fmemopen.3 | 2 +-
> man/man3/fread.3 | 4 ++--
> man/man3/getcwd.3 | 2 +-
> man/man3/getdirentries.3 | 2 +-
> man/man3/getentropy.3 | 2 +-
> man/man3/getgrent_r.3 | 4 ++--
> man/man3/getgrnam.3 | 4 ++--
> man/man3/gethostbyname.3 | 10 +++++-----
> man/man3/getipnodebyname.3 | 2 +-
> man/man3/getlogin.3 | 2 +-
> man/man3/getmntent.3 | 2 +-
> man/man3/getnameinfo.3 | 2 +-
> man/man3/getnetent_r.3 | 6 +++---
> man/man3/getprotoent_r.3 | 6 +++---
> man/man3/getpwent_r.3 | 4 ++--
> man/man3/getpwnam.3 | 4 ++--
> man/man3/getrpcent_r.3 | 6 +++---
> man/man3/getservent_r.3 | 6 +++---
> man/man3/getspnam.3 | 8 ++++----
> man/man3/inet_net_pton.3 | 4 ++--
> man/man3/inet_ntop.3 | 2 +-
> man/man3/lio_listio.3 | 2 +-
> man/man3/lsearch.3 | 4 ++--
> man/man3/mblen.3 | 2 +-
> man/man3/mbrlen.3 | 2 +-
> man/man3/mbrtowc.3 | 2 +-
> man/man3/mbsnrtowcs.3 | 2 +-
> man/man3/mbsrtowcs.3 | 2 +-
> man/man3/mbstowcs.3 | 2 +-
> man/man3/mbtowc.3 | 2 +-
> man/man3/memccpy.3 | 2 +-
> man/man3/memchr.3 | 2 +-
> man/man3/memcmp.3 | 2 +-
> man/man3/memcpy.3 | 2 +-
> man/man3/memfrob.3 | 2 +-
> man/man3/memmem.3 | 2 +-
> man/man3/memmove.3 | 2 +-
> man/man3/mempcpy.3 | 2 +-
> man/man3/memrchr.3 | 2 +-
> man/man3/memset.3 | 2 +-
> man/man3/memset_explicit.3 | 2 +-
> man/man3/mq_receive.3 | 4 ++--
> man/man3/mq_send.3 | 4 ++--
> man/man3/posix_madvise.3 | 2 +-
> man/man3/pthread_attr_setstack.3 | 2 +-
> man/man3/pthread_setname_np.3 | 2 +-
> man/man3/ptsname.3 | 2 +-
> man/man3/qsort.3 | 4 ++--
> man/man3/random.3 | 2 +-
> man/man3/regex.3 | 2 +-
> man/man3/resolver.3 | 24 ++++++++++++------------
> man/man3/setaliasent.3 | 4 ++--
> man/man3/setbuf.3 | 4 ++--
> man/man3/setnetgrent.3 | 2 +-
> man/man3/snprintf.3 | 4 ++--
> man/man3/stpncpy.3 | 2 +-
> man/man3/strerror.3 | 4 ++--
> man/man3/strfmon.3 | 4 ++--
> man/man3/strfromd.3 | 6 +++---
> man/man3/strftime.3 | 4 ++--
> man/man3/strlcpy.3 | 4 ++--
> man/man3/strncat.3 | 2 +-
> man/man3/strncpy.3 | 2 +-
> man/man3/strndup.3 | 2 +-
> man/man3/strndupa.3 | 2 +-
> man/man3/strxfrm.3 | 2 +-
> man/man3/swab.3 | 2 +-
> man/man3/ttyname.3 | 2 +-
> man/man3/unlocked_stdio.3 | 8 ++++----
> man/man3/wcpncpy.3 | 2 +-
> man/man3/wcsncat.3 | 2 +-
> man/man3/wcsncpy.3 | 2 +-
> man/man3/wcsnrtombs.3 | 2 +-
> man/man3/wcsrtombs.3 | 2 +-
> man/man3/wcstombs.3 | 2 +-
> man/man3/wmemchr.3 | 2 +-
> man/man3/wmemcmp.3 | 2 +-
> man/man3/wmemcpy.3 | 2 +-
> man/man3/wmemmove.3 | 2 +-
> man/man3/wmempcpy.3 | 2 +-
> man/man3/wmemset.3 | 2 +-
> man/man3/wprintf.3 | 4 ++--
> man/man7/man-pages.7 | 2 +-
> man/man7/string_copying.7 | 16 ++++++++--------
> man/man9/strscpy.9 | 2 +-
> 144 files changed, 228 insertions(+), 228 deletions(-)
>
> diff --git a/man/man2/add_key.2 b/man/man2/add_key.2
> index 19bc5d40ae76..908c63a10fbb 100644
> --- a/man/man2/add_key.2
> +++ b/man/man2/add_key.2
> @@ -14,7 +14,7 @@ .SH SYNOPSIS
> .nf
> .B #include <keyutils.h>
> .P
> -.BR key_serial_t\~add_key( size_t\~size;
> +.B key_serial_t\~add_key(
> .BI " const char *" type ", const char *" description ,
> .BI " const void " payload [ size "], size_t " size ,
> .BI " key_serial_t " keyring ");"
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH] man/: SYNOPSIS: Remove GNU forward-declarations of parameters for lengths of array parameters
2026-10-22 17:11 ` Martin Uecker
@ 2026-10-22 20:01 ` Alejandro Colomar
2026-10-22 20:27 ` Alejandro Colomar
0 siblings, 1 reply; 27+ messages in thread
From: Alejandro Colomar @ 2026-10-22 20:01 UTC (permalink / raw)
To: Martin Uecker
Cc: Alejandro Colomar, linux-man, Michael Kerrisk, Christopher Bazley,
Sam James, Carlos O'Donell, Joseph S. Myers
[-- Attachment #1: Type: text/plain, Size: 2184 bytes --]
Hi Martin,
> Date: 2026-10-22 19:11:41+0200
> From: Martin Uecker <uecker@tugraz.at>
>
>
> Here are my 2 cents:
>
> The one big advantage of the forward declaration syntax is, that
> if one does use it, one can get real benefits in security already
> today in the forms of compiler warnings and when using object-size
> sanitizer. In my opinion, it is real tragedy for the world that it
> is not more widely known and used (and that Clang does not want to
> implement it).
In this case, we're only concerned about documentation. I fully agree
that in source code, forward declarations are the way to go. What we're
trying to decide here is whether the same is true in documentation or
whether there are reasons to do something else.
> On the other hand, we have now a counter proposal from Apple
> which would make the simpler syntax with retrospective scoping
> work.
I'm not sure about that. There are concerns about it changing the
meaning of existing code if the constraint is not added (and if it is
added, of breaking code at a distance). That proposal is not yet ready.
And indeed, some of those concerns are related to the concerns I have in
manual pages: if users take this syntax and start using it, they might
have serious issues in their code.
> I still do not like it, as the fully developed form
> would be a major pain for most C compiler to implement, but
> I guess a restricted version would be ok. Unfortunately, this
> syntax does not work today, so could be used in code only at
> some point in the future.
>
> Still, my recommendation would be to wait until this issue is settled
> in WG14 and if Apple's proposal is accepted, use Apple's syntax
> in the man pages.
Yes, if Apple's syntax is accepted, we should probably change the
documentation. Michael thinks there are reasons to move earlier,
though. I'm not entirely convinced about his position.
I see that he's worried about users hitting a spike of confusion reading
this GNU C syntax in manual pages. I'm not convinced that this will
last for long, though.
Have a lovely night!
Alex
--
<https://www.alejandro-colomar.es>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] man/: SYNOPSIS: Remove GNU forward-declarations of parameters for lengths of array parameters
2026-10-22 20:01 ` Alejandro Colomar
@ 2026-10-22 20:27 ` Alejandro Colomar
0 siblings, 0 replies; 27+ messages in thread
From: Alejandro Colomar @ 2026-10-22 20:27 UTC (permalink / raw)
To: Martin Uecker
Cc: linux-man, Michael Kerrisk, Christopher Bazley, Sam James,
Carlos O'Donell, Joseph S. Myers
[-- Attachment #1: Type: text/plain, Size: 3736 bytes --]
Hi Martin,
> Date: 2026-10-22 22:01:17+0200
> From: Alejandro Colomar <alx+linux-man@kernel.org>
>
[...]
> > I still do not like it, as the fully developed form
> > would be a major pain for most C compiler to implement, but
> > I guess a restricted version would be ok. Unfortunately, this
> > syntax does not work today, so could be used in code only at
> > some point in the future.
This syntax is useless for us. We have several functions that need to
write expressions in array lengths, and not just identifiers. We even
dereference some pointer types (see getsockopt(2), lfind(3), and
lsearch(3)).
It's also useless for me as a programmer, since I need to do non-trivial
stuff in my array sizes. Whatever we add to the language should work
for arbitrary types and expressions.
Here's a list of functions we have documented and which need a
non-restricted feature.
long get_mempolicy(unsigned long maxnode;
int *mode,
unsigned long nodemask[(maxnode + ULONG_WIDTH - 1)
/ ULONG_WIDTH],
unsigned long maxnode, void *addr,
unsigned long flags);
char *inet_net_ntop(int bits, size_t psize;
int af,
const void netp[(bits - CHAR_BIT + 1) / CHAR_BIT],
int bits,
char pres[psize], size_t psize);
int getsockopt(socklen_t *restrict optlen;
int sockfd, int level, int optname,
void optval[_Nullable restrict *optlen],
socklen_t *restrict optlen);
void *bsearch(size_t n, size_t size;
const void key[size], const void base[size * n],
size_t n, size_t size,
typeof(int (const void [size], const void [size]))
*compar);
/* In SCO OpenServer */
void cfree(unsigned int n, unsigned int size;
char ptr[size * n], unsigned int n, unsigned int size);
/* In Solaris watchmalloc.so.1 */
void cfree(size_t n, size_t size;
void ptr[size * n], size_t n, size_t size);
size_t fread(size_t size, size_t n;
void ptr[restrict size * n],
size_t size, size_t n,
FILE *restrict stream);
size_t fwrite(size_t size, size_t n;
const void ptr[restrict size * n],
size_t size, size_t n,
FILE *restrict stream);
size_t fread_unlocked(size_t size, size_t n;
void ptr[restrict size * n],
size_t size, size_t n,
FILE *restrict stream);
size_t fwrite_unlocked(size_t size, size_t n;
const void ptr[restrict size * n],
size_t size, size_t n,
FILE *restrict stream);
void *lfind(size_t *n, size_t size;
const void key[size],
const void base[*n * size],
size_t *n, size_t size,
typeof(int (const void [size], const void [size]))
*compar);
void *lsearch(size_t *n, size_t size;
const void key[size],
void base[*n * size],
size_t *n, size_t size,
typeof(int (const void [size], const void [size]))
*compar);
I might have missed some other functions; I think this isn't exhaustive.
Cheers,
Alex
--
<https://www.alejandro-colomar.es>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] man/: SYNOPSIS: Remove GNU forward-declarations of parameters for lengths of array parameters
2026-10-22 16:44 [PATCH] man/: SYNOPSIS: Remove GNU forward-declarations of parameters for lengths of array parameters Alejandro Colomar
2026-10-22 17:11 ` Martin Uecker
@ 2026-10-22 17:37 ` Christopher Bazley
[not found] ` <CAEHU8x9jET+vcrR0NpDz6t57egQG8TZqx5XtV52srH9ZRvdxSQ@mail.gmail.com>
2026-10-22 22:03 ` Mark Harris
3 siblings, 0 replies; 27+ messages in thread
From: Christopher Bazley @ 2026-10-22 17:37 UTC (permalink / raw)
To: linux-man
Hi Alejandro,
On Thu, 22 Oct 2026 at 17:45, Alejandro Colomar <alx@kernel.org> wrote:
> From: Alejandro Colomar <alx+linux-man@kernel.org>
>
> From: Alejandro Colomar <alx@kernel.org>
>
> I'm not fully convinced of this patch. But I'm open to being convinced.
> I've written the patch, as Michael asked me to do, but am willing to
> hear everyone's opinion before applying the patch.
Why did Michael ask you to do this? I think there is some context missing.
> As Michael reminded me recently, and as I've defended in other cases, it
> is true that the SYNOPSIS of the manual pages does not need to be
> strictly valid C. It only needs to be useful enough for readers to
> understand the interface. Thus, if using lengths without declaring them
> would improve the usefulness of the documentation, even if becoming
> invalid C, it would be okay.
>
> However, I still have doubts, because this change comes with risks:
>
> Programmers might think it is valid C to refer to parameters that have
> not been declared yet, and use that in their code, and if they are
> unlucky, it might compile for them, which might result in UB at some
> point.
>
I think it is reasonable to assume that anything which resembles C source
code will at some point be copied and pasted into a C program.
> One valid point is that this is rather unlikely to happen, and most of
> the time it will just result in a compiler error, because no global
> variables with the name of the parameter exist.
>
> However, with local (nested) functions, this might be easier to happen,
> as variables declared in the outer function are more likely to share a
> name with a length parameter. Given that the C Committee is working
> hard to standardize local functions, it might be a very bad idea to have
> this combination of events going on.
>
I agree with this concern in general, although I don.t quite see how it
applies in the specific case of the functions that you are documenting.
(Unless you are expecting those functions to be declared inside a function
definition instead of by including the appropriate header - in which case
the hazard already exists.)
I guess you are really worried about people copying the style rather than
the content.
> Concerns that have been raised against using the GNU C syntax in the
> manual pages:
Parameter forward declarations are also supported by SDCC, albeit with more
limitations. I would be interested to see whether your usage falls into the
category of usage that would be supported by SDCC or not.
> Very very few programmers know this syntax, and thus they are confused
> when reading it for the first time.
>
> This is obviously true. However, this is true of any innovative syntax.
> We should consider whether the confusion is dangerous or not, and
> whether programmers can learn it easily or not.
>
Can we still call it innovative, many decades after its invention?
>
> I believe once you've been exposed to this syntax, after some research,
> or asking the right people, one would easily learn to read it, and then
> we'd have overcome the issue. I don't think the syntax is inherently
> difficult to understand once you've seen the documentation and seen it
> a few times.
>
> Also, this syntax is not very dangerous: a programmer thinking
> that a forward declaration is actually a normal parameter will pass a
> wrong number of arguments to the function, and thus will have compiler
> errors. This syntax is quite robust, as it requires several bugs to
> happen in the same code to pass compilation silently. If one replaces
> ';' with ',', the parameter will be declared twice, which is an error.
> If one renames a forward declaration, it will not match a parameter, and
> will result in a compiler error. Only if both mistakes happen at once,
> the compilation would pass, but then the call sites would also have to
> match the bogus declaration. And also, the function definition would
> have unused parameters, which would trigger diagnostics. So, concerning
> safety, this feature is not very dangerous, even if used by someone who
> is very confused.
>
> Do we think programmers are unable to ever learn this new syntax?
No, because programmers are clever and it is relatively simple. I wrote a
paper that explored the drawbacks of the syntax and recommended
standardising a subset (which I assume is what you are using). With a free
hand, I might have been tempted to go further, but it is well-established
and impossible to redefine.
I still have not yet seen a proposal for anything easier to learn (that
does not rely on forward-parsing).
> Are we ready to accept the risks of using the dangerous invalid syntax,
> but which is more intuitive to programmers?
>
> Reported-by: Michael Kerrisk <mtk.manpages@gmail.com>
> Not-yet-Signed-off-by: Alejandro Colomar <alx@kernel.org>
> ---
>
> I've cut the diff below to just a single page, because this is just for
> discussion; the actual diff is huge and uninteresting. It's just a
> removal of all uses of fwd decls of parameters in the manual pages.
>
I don't agree with the change, but the fact that there are no useful ISO C
semantics for parameters of pointer type declared using array syntax
weakens my concern. (If the parameters actually had variably-modified types
then the change would be far worse, from my point of view, because the
parameter types would no longer be expressed correctly.)
You know your customers better than I do. If they expect GNU C semantics,
then it seems reasonable to document those semantics using GNU C syntax.
Christopher
^ permalink raw reply [flat|nested] 27+ messages in thread[parent not found: <CAEHU8x9jET+vcrR0NpDz6t57egQG8TZqx5XtV52srH9ZRvdxSQ@mail.gmail.com>]
* Re: [PATCH] man/: SYNOPSIS: Remove GNU forward-declarations of parameters for lengths of array parameters
[not found] ` <CAEHU8x9jET+vcrR0NpDz6t57egQG8TZqx5XtV52srH9ZRvdxSQ@mail.gmail.com>
@ 2026-10-22 19:54 ` Alejandro Colomar
2026-10-23 11:53 ` Michael Kerrisk (man7.org)
2026-10-23 12:11 ` Alejandro Colomar
0 siblings, 2 replies; 27+ messages in thread
From: Alejandro Colomar @ 2026-10-22 19:54 UTC (permalink / raw)
To: Christopher Bazley
Cc: linux-man, Michael Kerrisk, Sam James, Carlos O'Donell,
Joseph S. Myers, Martin Uecker
[-- Attachment #1: Type: text/plain, Size: 7488 bytes --]
Hi Chris,
> Date: 2026-10-22 18:29:31+0100
> From: Christopher Bazley <chris.bazley.wg14@gmail.com>
>
> Hi Alejandro,
>
> On Thu, 22 Oct 2026 at 17:45, Alejandro Colomar <alx@kernel.org> wrote:
>
> > From: Alejandro Colomar <alx+linux-man@kernel.org>
> >
> > From: Alejandro Colomar <alx@kernel.org>
> >
> > I'm not fully convinced of this patch. But I'm open to being convinced.
> > I've written the patch, as Michael asked me to do, but am willing to
> > hear everyone's opinion before applying the patch.
>
>
> Why did Michael ask you to do this? I think there is some context missing.
We have dozens of users having reported a bug in the documentation,
as they believe the forward declarations are an accident/typo.
Clearly, most readers don't know this syntax, and think it's some
mistake. I've been dealing with them nicely explaining them the
existance and validity of the syntax, and they tend to understand it
quickly.
> > As Michael reminded me recently, and as I've defended in other cases, it
> > is true that the SYNOPSIS of the manual pages does not need to be
> > strictly valid C. It only needs to be useful enough for readers to
> > understand the interface. Thus, if using lengths without declaring them
> > would improve the usefulness of the documentation, even if becoming
> > invalid C, it would be okay.
> >
> > However, I still have doubts, because this change comes with risks:
> >
> > Programmers might think it is valid C to refer to parameters that have
> > not been declared yet, and use that in their code, and if they are
> > unlucky, it might compile for them, which might result in UB at some
> > point.
> >
>
>
> I think it is reasonable to assume that anything which resembles C source
> code will at some point be copied and pasted into a C program.
Indeed.
> > One valid point is that this is rather unlikely to happen, and most of
> > the time it will just result in a compiler error, because no global
> > variables with the name of the parameter exist.
> >
> > However, with local (nested) functions, this might be easier to happen,
> > as variables declared in the outer function are more likely to share a
> > name with a length parameter. Given that the C Committee is working
> > hard to standardize local functions, it might be a very bad idea to have
> > this combination of events going on.
> >
>
> I agree with this concern in general, although I don’t quite see how it
> applies in the specific case of the functions that you are documenting.
> (Unless you are expecting those functions to be declared inside a function
> definition instead of by including the appropriate header — in which case
> the hazard already exists.)
>
> I guess you are really worried about people copying the style rather than
> the content.
Indeed, my worry is not that people will copy these declarations
verbatim, but that they'll think it is valid, and write similar code for
their own declarations.
> > Concerns that have been raised against using the GNU C syntax in the
> > manual pages:
>
>
> Parameter forward declarations are also supported by SDCC, albeit with more
> limitations. I would be interested to see whether your usage falls into the
> category of usage that would be supported by SDCC or not.
Our users are mainly interested in POSIX compilers. That is more or
less GCC, Clang, TCC, PCC, and maybe something like Intel or IBM
compilers. The main two are GCC and Clang.
> > Very very few programmers know this syntax, and thus they are confused
> > when reading it for the first time.
> >
> > This is obviously true. However, this is true of any innovative syntax.
> > We should consider whether the confusion is dangerous or not, and
> > whether programmers can learn it easily or not.
> >
>
> Can we still call it innovative, many decades after its invention?
Maybe I should have used the term 'novel' rather than innovative.
While it's clearly not new, being decades old, it is certainly a novelty
to the programmers that have never seen it before.
> > I believe once you've been exposed to this syntax, after some research,
> > or asking the right people, one would easily learn to read it, and then
> > we'd have overcome the issue. I don't think the syntax is inherently
> > difficult to understand once you've seen the documentation and seen it
> > a few times.
> >
> > Also, this syntax is not very dangerous: a programmer thinking
> > that a forward declaration is actually a normal parameter will pass a
> > wrong number of arguments to the function, and thus will have compiler
> > errors. This syntax is quite robust, as it requires several bugs to
> > happen in the same code to pass compilation silently. If one replaces
> > ';' with ',', the parameter will be declared twice, which is an error.
> > If one renames a forward declaration, it will not match a parameter, and
> > will result in a compiler error. Only if both mistakes happen at once,
> > the compilation would pass, but then the call sites would also have to
> > match the bogus declaration. And also, the function definition would
> > have unused parameters, which would trigger diagnostics. So, concerning
> > safety, this feature is not very dangerous, even if used by someone who
> > is very confused.
> >
> > Do we think programmers are unable to ever learn this new syntax?
>
>
> No, because programmers are clever and it is relatively simple. I wrote a
> paper that explored the drawbacks of the syntax and recommended
> standardising a subset (which I assume is what you are using).
[...]
Agree.
> I still have not yet seen a proposal for anything easier to learn (that
> does not rely on forward-parsing).
Agree. But indeed the counter-proposal that I've received is to use
retroactive scoping in the manual pages.
> > Are we ready to accept the risks of using the dangerous invalid syntax,
> > but which is more intuitive to programmers?
> >
> > Reported-by: Michael Kerrisk <mtk.manpages@gmail.com>
> > Not-yet-Signed-off-by: Alejandro Colomar <alx@kernel.org>
> > ---
> >
> > I've cut the diff below to just a single page, because this is just for
> > discussion; the actual diff is huge and uninteresting. It's just a
> > removal of all uses of fwd decls of parameters in the manual pages.
> >
>
> I don’t agree with the change,
Thanks!
> but the fact that there are no useful ISO C
> semantics for parameters of pointer type declared using array syntax
> weakens my concern. (If the parameters actually had variably-modified types
> then the change would be far worse, from my point of view, because the
> parameter types would no longer be expressed correctly.)
We don't care about what ISO C says. GNU C clearly assigns semantics to
array parameters, and that means we have to be careful about them here.
If this can result in sanitizers breaking code, it is something to be
careful about. Moreover, I hope ISO C eventually catches up.
> You know your customers better than I do. If they expect GNU C semantics,
> then it seems reasonable to document those semantics using GNU C syntax.
Agree.
Have a lovely night!
Alex
P.S.: I see two emails from you; are they the same? One has a smaller
recipient list, but the contents seem visually the same.
>
> Christopher
--
<https://www.alejandro-colomar.es>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH] man/: SYNOPSIS: Remove GNU forward-declarations of parameters for lengths of array parameters
2026-10-22 19:54 ` Alejandro Colomar
@ 2026-10-23 11:53 ` Michael Kerrisk (man7.org)
2026-10-23 12:42 ` Alejandro Colomar
2026-10-23 15:51 ` Christopher Bazley
2026-10-23 12:11 ` Alejandro Colomar
1 sibling, 2 replies; 27+ messages in thread
From: Michael Kerrisk (man7.org) @ 2026-10-23 11:53 UTC (permalink / raw)
To: Alejandro Colomar
Cc: Christopher Bazley, linux-man, Michael Kerrisk, Sam James,
Carlos O'Donell, Joseph S. Myers, Martin Uecker
Hello,
On Thu, 22 Oct 2026 at 16:54, Alejandro Colomar
<alx+linux-man@kernel.org> wrote:
>
> Hi Chris,
>
> > Date: 2026-10-22 18:29:31+0100
> > From: Christopher Bazley <chris.bazley.wg14@gmail.com>
> >
> > Hi Alejandro,
> >
> > On Thu, 22 Oct 2026 at 17:45, Alejandro Colomar <alx@kernel.org> wrote:
> >
> > > From: Alejandro Colomar <alx+linux-man@kernel.org>
> > >
> > > From: Alejandro Colomar <alx@kernel.org>
> > >
> > > I'm not fully convinced of this patch. But I'm open to being convinced.
> > > I've written the patch, as Michael asked me to do, but am willing to
> > > hear everyone's opinion before applying the patch.
> >
> > Why did Michael ask you to do this? I think there is some context missing.
>
> We have dozens of users having reported a bug in the documentation,
> as they believe the forward declarations are an accident/typo.
> Clearly, most readers don't know this syntax, and think it's some
> mistake. I've been dealing with them nicely explaining them the
> existance and validity of the syntax, and they tend to understand it
> quickly.
I spoke with Alex a couple of times about this in person. Via man7.org
I have received numerous bug reports about this syntax. It is
nonstandard, people are not at all familiar with it, and they will
potentially misinterpret it in ways that will lead them to make errors
when writing code.
> > > As Michael reminded me recently, and as I've defended in other cases, it
> > > is true that the SYNOPSIS of the manual pages does not need to be
> > > strictly valid C. It only needs to be useful enough for readers to
> > > understand the interface. Thus, if using lengths without declaring them
> > > would improve the usefulness of the documentation, even if becoming
> > > invalid C, it would be okay.
> > >
> > > However, I still have doubts, because this change comes with risks:
> > >
> > > Programmers might think it is valid C to refer to parameters that have
> > > not been declared yet, and use that in their code, and if they are
> > > unlucky, it might compile for them, which might result in UB at some
> > > point.
> >
> > I think it is reasonable to assume that anything which resembles C source
> > code will at some point be copied and pasted into a C program.
>
> Indeed.
>
> > > One valid point is that this is rather unlikely to happen, and most of
> > > the time it will just result in a compiler error, because no global
> > > variables with the name of the parameter exist.
> > >
> > > However, with local (nested) functions, this might be easier to happen,
> > > as variables declared in the outer function are more likely to share a
> > > name with a length parameter. Given that the C Committee is working
> > > hard to standardize local functions, it might be a very bad idea to have
> > > this combination of events going on.
> > >
> >
> > I agree with this concern in general, although I don’t quite see how it
> > applies in the specific case of the functions that you are documenting.
> > (Unless you are expecting those functions to be declared inside a function
> > definition instead of by including the appropriate header — in which case
> > the hazard already exists.)
> >
> > I guess you are really worried about people copying the style rather than
> > the content.
>
> Indeed, my worry is not that people will copy these declarations
> verbatim, but that they'll think it is valid, and write similar code for
> their own declarations.
>
> > > Concerns that have been raised against using the GNU C syntax in the
> > > manual pages:
> >
> >
> > Parameter forward declarations are also supported by SDCC, albeit with more
> > limitations. I would be interested to see whether your usage falls into the
> > category of usage that would be supported by SDCC or not.
>
> Our users are mainly interested in POSIX compilers. That is more or
> less GCC, Clang, TCC, PCC, and maybe something like Intel or IBM
> compilers. The main two are GCC and Clang.
>
> > > Very very few programmers know this syntax, and thus they are confused
> > > when reading it for the first time.
> > >
> > > This is obviously true. However, this is true of any innovative syntax.
> > > We should consider whether the confusion is dangerous or not, and
> > > whether programmers can learn it easily or not.
> >
> > Can we still call it innovative, many decades after its invention?
>
> Maybe I should have used the term 'novel' rather than innovative.
> While it's clearly not new, being decades old, it is certainly a novelty
> to the programmers that have never seen it before.
>
> > > I believe once you've been exposed to this syntax, after some research,
> > > or asking the right people, one would easily learn to read it, and then
> > > we'd have overcome the issue. I don't think the syntax is inherently
> > > difficult to understand once you've seen the documentation and seen it
> > > a few times.
> > >
> > > Also, this syntax is not very dangerous: a programmer thinking
> > > that a forward declaration is actually a normal parameter will pass a
> > > wrong number of arguments to the function, and thus will have compiler
> > > errors. This syntax is quite robust, as it requires several bugs to
> > > happen in the same code to pass compilation silently. If one replaces
> > > ';' with ',', the parameter will be declared twice, which is an error.
> > > If one renames a forward declaration, it will not match a parameter, and
> > > will result in a compiler error. Only if both mistakes happen at once,
> > > the compilation would pass, but then the call sites would also have to
> > > match the bogus declaration. And also, the function definition would
> > > have unused parameters, which would trigger diagnostics. So, concerning
> > > safety, this feature is not very dangerous, even if used by someone who
> > > is very confused.
It is not enough to say that the compiler will warn people about the
incorrect arguments. I have seen people do the strangest (incorrect)
things to "fix" warnings and errors they get from the compiler.
> > > Do we think programmers are unable to ever learn this new syntax?
> >
> > No, because programmers are clever and it is relatively simple. I wrote a
> > paper that explored the drawbacks of the syntax and recommended
> > standardising a subset (which I assume is what you are using).
I have talked with programmers with *decades* of C programming
experience who are unfamiliar with this syntax. Indeed, when I first
got bug reports about, I also was unfamiliar with it, and thought it
was just a bug in the manual page.
> [...]
>
> Agree.
>
> > I still have not yet seen a proposal for anything easier to learn (that
> > does not rely on forward-parsing).
>
> Agree. But indeed the counter-proposal that I've received is to use
> retroactive scoping in the manual pages.
>
> > > Are we ready to accept the risks of using the dangerous invalid syntax,
> > > but which is more intuitive to programmers?
> > >
> > > Reported-by: Michael Kerrisk <mtk.manpages@gmail.com>
> > > Not-yet-Signed-off-by: Alejandro Colomar <alx@kernel.org>
> > > ---
> > >
> > > I've cut the diff below to just a single page, because this is just for
> > > discussion; the actual diff is huge and uninteresting. It's just a
> > > removal of all uses of fwd decls of parameters in the manual pages.
> > >
> >
> > I don’t agree with the change,
>
> Thanks!
>
> > but the fact that there are no useful ISO C
> > semantics for parameters of pointer type declared using array syntax
> > weakens my concern. (If the parameters actually had variably-modified types
> > then the change would be far worse, from my point of view, because the
> > parameter types would no longer be expressed correctly.)
>
> We don't care about what ISO C says. GNU C clearly assigns semantics to
> array parameters, and that means we have to be careful about them here.
> If this can result in sanitizers breaking code, it is something to be
> careful about. Moreover, I hope ISO C eventually catches up.
>
> > You know your customers better than I do. If they expect GNU C semantics,
> > then it seems reasonable to document those semantics using GNU C syntax.
The customers clearly do NOT expect GNU C syntax.
My preference would be the earlier status quo: standard C syntax, with
an explanation in the manual page text that explains the relationship
between the arguments. The current proposed patch is a compromise: it
has the disadvantage of being nonstandard C, but does at least clearly
hint at the relationship between the arguments.
Thanks,
Michael
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] man/: SYNOPSIS: Remove GNU forward-declarations of parameters for lengths of array parameters
2026-10-23 11:53 ` Michael Kerrisk (man7.org)
@ 2026-10-23 12:42 ` Alejandro Colomar
2026-10-23 15:51 ` Christopher Bazley
1 sibling, 0 replies; 27+ messages in thread
From: Alejandro Colomar @ 2026-10-23 12:42 UTC (permalink / raw)
To: Michael Kerrisk (man7.org)
Cc: Christopher Bazley, linux-man, Michael Kerrisk, Sam James,
Carlos O'Donell, Joseph S. Myers, Martin Uecker,
Guillem Jover, g.branden.robinson, Günther Noack,
Ahelenia Ziemiańska
[-- Attachment #1: Type: text/plain, Size: 5042 bytes --]
Hi Michael,
> Date: 2026-10-23 08:53:22-0300
> From: "Michael Kerrisk (man7.org)" <mtk@man7.org>
>
[...]
> > > > Also, this syntax is not very dangerous: a programmer thinking
> > > > that a forward declaration is actually a normal parameter will pass a
> > > > wrong number of arguments to the function, and thus will have compiler
> > > > errors. This syntax is quite robust, as it requires several bugs to
> > > > happen in the same code to pass compilation silently. If one replaces
> > > > ';' with ',', the parameter will be declared twice, which is an error.
> > > > If one renames a forward declaration, it will not match a parameter, and
> > > > will result in a compiler error. Only if both mistakes happen at once,
> > > > the compilation would pass, but then the call sites would also have to
> > > > match the bogus declaration. And also, the function definition would
> > > > have unused parameters, which would trigger diagnostics. So, concerning
> > > > safety, this feature is not very dangerous, even if used by someone who
> > > > is very confused.
>
> It is not enough to say that the compiler will warn people about the
> incorrect arguments. I have seen people do the strangest (incorrect)
> things to "fix" warnings and errors they get from the compiler.
Hmmmm.
> > > > Do we think programmers are unable to ever learn this new syntax?
> > >
> > > No, because programmers are clever and it is relatively simple. I wrote a
> > > paper that explored the drawbacks of the syntax and recommended
> > > standardising a subset (which I assume is what you are using).
>
> I have talked with programmers with *decades* of C programming
> experience who are unfamiliar with this syntax. Indeed, when I first
> got bug reports about, I also was unfamiliar with it, and thought it
> was just a bug in the manual page.
I agree with this. Very very few people knew about this feature until
it started being discussed recently, and still very few people know
about it. I only knew about it around 3 years ago or so.
What I wonder is whether people can get familiar with it in one or two
years of exposure to it.
One way to test that would be to wait until Fedora contains this syntax
at least in one release, to get it exposed to more programmers. So far,
Fedora remains in man-pages-6.13, and the first version with this
syntax was 6.14 (1.5 years ago). Carlos is working on getting the
packaging updated.
There are risks in both alternatives: if we have the GNU C syntax,
there's a risk with programmers workarounding compiler errors in weird
ways. If we have the invalid syntax without forward declarations, the
risk is in people using that syntax in their own code and triggering UB
or least logic errors. The latter risk is a persistent one; there's no
expectation that the risk will ever decrease. The former risk (that of
using GNU C syntax), I expect the risk to be temporary, until
programmers get accustomed to this syntax.
I'd accept adding this patch if there's an overwhelming majority that
I'm being a bit paranoid about the risk of using invalid syntax, and
that I'm understating the risk of using GNU C syntax.
I'd like to hear explicit comments from Carlos, Sam, and Joseph before
taking a decision. But if they seem to agree with that point of view,
I'd take the patch, even with my own NAK (I'm willing to document both
ACKs and NAKs).
I've now also CCed a few more people, since I'm also curious about their
opinions.
So far, the patch would have:
Reported-by: Michael Kerrisk <mtk.manpages@gmail.com>
Nacked-by: Alejandro Colomar <alx@kernel.org>
Nacked-by: Martin Uecker <uecker@tugraz.at>
Nacked-by: Christopher Bazley <chris.bazley.wg14@gmail.com>
Acked-by: Mark Harris <mark.hsj@gmail.com>
Acked-by: Michael Kerrisk <mtk.manpages@gmail.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
(those ACKs and NAKs transformed from messages saying they want or don't
want the patch.)
(Before anyone comments the possibility of going back to simple pointer
syntax, that's certainly not coming back. The information about array
lengths is fundamental in the SYNOPSIS.)
[...]
> My preference would be the earlier status quo: standard C syntax, with
As a reminder, it was never standard C syntax. We have always had
non-standard exceptions in prototypes, such as open(2) having two
declarations (as if C++ overload syntax). It was ISO C syntax regarding
array parameters, though: we used pointer syntax. But as said above,
I really disliked having that information only in the DESCRIPTION.
> an explanation in the manual page text that explains the relationship
> between the arguments. The current proposed patch is a compromise: it
> has the disadvantage of being nonstandard C, but does at least clearly
> hint at the relationship between the arguments.
Agree.
Have a lovely day!
Alex
> Thanks,
>
> Michael
--
<https://www.alejandro-colomar.es>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] man/: SYNOPSIS: Remove GNU forward-declarations of parameters for lengths of array parameters
2026-10-23 11:53 ` Michael Kerrisk (man7.org)
2026-10-23 12:42 ` Alejandro Colomar
@ 2026-10-23 15:51 ` Christopher Bazley
2026-10-24 12:45 ` Michael Kerrisk (man7.org)
1 sibling, 1 reply; 27+ messages in thread
From: Christopher Bazley @ 2026-10-23 15:51 UTC (permalink / raw)
To: Michael Kerrisk (man7.org)
Cc: Alejandro Colomar, linux-man, Michael Kerrisk, Sam James,
Carlos O'Donell, Joseph S. Myers, Martin Uecker
Hi Michael,
On Fri, Oct 23, 2026 at 12:54 PM Michael Kerrisk (man7.org)
<mtk@man7.org> wrote:
>
> Hello,
>
> On Thu, 22 Oct 2026 at 16:54, Alejandro Colomar
> <alx+linux-man@kernel.org> wrote:
> >
> > Hi Chris,
> >
> > > Date: 2026-10-22 18:29:31+0100
> > > From: Christopher Bazley <chris.bazley.wg14@gmail.com>
...
> > > You know your customers better than I do. If they expect GNU C semantics,
> > > then it seems reasonable to document those semantics using GNU C syntax.
>
> The customers clearly do NOT expect GNU C syntax.
>
> My preference would be the earlier status quo: standard C syntax, with
> an explanation in the manual page text that explains the relationship
> between the arguments. The current proposed patch is a compromise: it
> has the disadvantage of being nonstandard C, but does at least clearly
> hint at the relationship between the arguments.
I am curious to know what your attitude would be to lesser-known
standard C syntax.
For example:
int pipe(int pipefd[static 2]);
is standard C syntax, and requires the caller to pass a pointer to the
first of at least 2 array elements, unlike
int pipe(int pipefd[2]);
which has the same semantics in ISO C as
int pipe(int *pipefd);
Thanks,
Christopher
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] man/: SYNOPSIS: Remove GNU forward-declarations of parameters for lengths of array parameters
2026-10-23 15:51 ` Christopher Bazley
@ 2026-10-24 12:45 ` Michael Kerrisk (man7.org)
2026-10-24 13:38 ` Alejandro Colomar
0 siblings, 1 reply; 27+ messages in thread
From: Michael Kerrisk (man7.org) @ 2026-10-24 12:45 UTC (permalink / raw)
To: Christopher Bazley
Cc: Alejandro Colomar, linux-man, Michael Kerrisk, Sam James,
Carlos O'Donell, Joseph S. Myers, Martin Uecker
Hello Christopher
On Fri, 23 Oct 2026 at 17:51, Christopher Bazley
<chris.bazley.wg14@gmail.com> wrote:
>
> Hi Michael,
>
> On Fri, Oct 23, 2026 at 12:54 PM Michael Kerrisk (man7.org)
> <mtk@man7.org> wrote:
> >
> > Hello,
> >
> > On Thu, 22 Oct 2026 at 16:54, Alejandro Colomar
> > <alx+linux-man@kernel.org> wrote:
> > >
> > > Hi Chris,
> > >
> > > > Date: 2026-10-22 18:29:31+0100
> > > > From: Christopher Bazley <chris.bazley.wg14@gmail.com>
> ...
> > > > You know your customers better than I do. If they expect GNU C semantics,
> > > > then it seems reasonable to document those semantics using GNU C syntax.
> >
> > The customers clearly do NOT expect GNU C syntax.
> >
> > My preference would be the earlier status quo: standard C syntax, with
> > an explanation in the manual page text that explains the relationship
> > between the arguments. The current proposed patch is a compromise: it
> > has the disadvantage of being nonstandard C, but does at least clearly
> > hint at the relationship between the arguments.
>
> I am curious to know what your attitude would be to lesser-known
> standard C syntax.
>
> For example:
>
> int pipe(int pipefd[static 2]);comprehensible
>
> is standard C syntax, and requires the caller to pass a pointer to the
> first of at least 2 array elements, unlike
>
> int pipe(int pipefd[2]);
>
> which has the same semantics in ISO C as
>
> int pipe(int *pipefd);
I was unfamiliar with that syntax, but at least in context it is
immediately understandable, and I so I don't dislike it, And it is
standard C. I really don't think Linux man-pages is the place to
introducing nonstandard, GNU-specific syntax (that people clearly
don't understand).
Cheers,
Michael
--
Michael Kerrisk, man7.org Training and Consulting
mtk@man7.org, http://man7.org/training/
"The Linux Programming Interface" -- http://man7.org/tlpi/
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] man/: SYNOPSIS: Remove GNU forward-declarations of parameters for lengths of array parameters
2026-10-24 12:45 ` Michael Kerrisk (man7.org)
@ 2026-10-24 13:38 ` Alejandro Colomar
2026-10-24 16:16 ` Christopher Bazley
0 siblings, 1 reply; 27+ messages in thread
From: Alejandro Colomar @ 2026-10-24 13:38 UTC (permalink / raw)
To: Michael Kerrisk (man7.org)
Cc: Christopher Bazley, linux-man, Michael Kerrisk, Sam James,
Carlos O'Donell, Joseph S. Myers, Martin Uecker
[-- Attachment #1: Type: text/plain, Size: 2461 bytes --]
Hi Michael,
> Date: 2026-10-24 09:45:02-0300
> From: "Michael Kerrisk (man7.org)" <mtk@man7.org>
>
> Hello Christopher
>
[...]
> > I am curious to know what your attitude would be to lesser-known
> > standard C syntax.
> >
> > For example:
> >
> > int pipe(int pipefd[static 2]);comprehensible
> >
> > is standard C syntax, and requires the caller to pass a pointer to the
> > first of at least 2 array elements, unlike
> >
> > int pipe(int pipefd[2]);
> >
> > which has the same semantics in ISO C as
> >
> > int pipe(int *pipefd);
>
> I was unfamiliar with that syntax, but at least in context it is
> immediately understandable,
Actually, it is not understandable. [static 2] doesn't mean the same as
[2], and this is one historic mistake of the C Committee that I wish had
never happened. [static 2] is never what you want (I was tempted to say
almost never, but I've never seen a good case for it). Programmers want
the meaning of [2].
The main differences between [static 2] and [2] are:
- [2] means (in GNU C, and in common understanding, but not
acknowledged by ISO C) that:
- The caller must supply at least 2 elements.
- The callee must not access past those 2 elements.
- [static 2] means (in ISO C, but ignored by GCC):
- The caller must supply at least 2 elements.
- The callee is free to access past those 2 elements!!
(of course, if there aren't any elements after that, it's UB)
- The caller must supply a non-null pointer.
The null-pointer issue is nonsense, but we can live with it.
The allowance to access past the specified length, that's the real issue
with this feature, and why it should not be used at all.
The committee was clearly confused when they added this feature.
It was around the time when 'restrict' was added, which is another
historical mistake of the committee. In general, every feature they
added thinking of optimizations (and that includes these two) has
resulted in a mistake.
> and I so I don't dislike it, And it is
> standard C.
When the standard clashes with reality and common sense, I'm not sure
I'd give the standard much credibility.
> I really don't think Linux man-pages is the place to
> introducing nonstandard, GNU-specific syntax (that people clearly
> don't understand).
People clearly don't understand [static 2] either.
Have a lovely day!
Alex
--
<https://www.alejandro-colomar.es>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] man/: SYNOPSIS: Remove GNU forward-declarations of parameters for lengths of array parameters
2026-10-24 13:38 ` Alejandro Colomar
@ 2026-10-24 16:16 ` Christopher Bazley
2026-10-24 16:37 ` Alejandro Colomar
0 siblings, 1 reply; 27+ messages in thread
From: Christopher Bazley @ 2026-10-24 16:16 UTC (permalink / raw)
To: Alejandro Colomar
Cc: Michael Kerrisk (man7.org), linux-man, Michael Kerrisk, Sam James,
Carlos O'Donell, Joseph S. Myers, Martin Uecker
On Sat, Oct 24, 2026 at 2:38 PM Alejandro Colomar
<alx+linux-man@kernel.org> wrote:
>
> Hi Michael,
>
> > Date: 2026-10-24 09:45:02-0300
> > From: "Michael Kerrisk (man7.org)" <mtk@man7.org>
> >
> > Hello Christopher
> >
> [...]
> > > I am curious to know what your attitude would be to lesser-known
> > > standard C syntax.
> > >
> > > For example:
> > >
> > > int pipe(int pipefd[static 2]);comprehensible
> > >
> > > is standard C syntax, and requires the caller to pass a pointer to the
> > > first of at least 2 array elements, unlike
> > >
> > > int pipe(int pipefd[2]);
> > >
> > > which has the same semantics in ISO C as
> > >
> > > int pipe(int *pipefd);
> >
> > I was unfamiliar with that syntax, but at least in context it is
> > immediately understandable,
>
> Actually, it is not understandable. [static 2] doesn't mean the same as
> [2], and this is one historic mistake of the C Committee that I wish had
> never happened. [static 2] is never what you want (I was tempted to say
> almost never, but I've never seen a good case for it). Programmers want
> the meaning of [2].
>
> The main differences between [static 2] and [2] are:
>
> - [2] means (in GNU C, and in common understanding, but not
> acknowledged by ISO C) that:
>
> - The caller must supply at least 2 elements.
> - The callee must not access past those 2 elements.
>
> - [static 2] means (in ISO C, but ignored by GCC):
>
> - The caller must supply at least 2 elements.
> - The callee is free to access past those 2 elements!!
> (of course, if there aren't any elements after that, it's UB)
You can, of course, document for the benefit of callers that a
function does not read past the static array bound.
> - The caller must supply a non-null pointer.
>
> The null-pointer issue is nonsense, but we can live with it.
> The allowance to access past the specified length, that's the real issue
> with this feature, and why it should not be used at all.
Of the compilers I have tried, only SDCC currently warns about access
past the specified length, and it does so regardless of whether the
length is specified using 'static' or not:
int foo(int a[static 2])
{
return a[2]; // warning from SDCC
}
int bar(int a[2])
{
return a[2]; // warning from SDCC
}
https://godbolt.org/z/zf3nPerdn
(I'm tempted to report the warning produced in the 'static' case as a
bug, but in reality no warning is a conformance issue, so that
characterisation is subjective.)
> The committee was clearly confused when they added this feature.
> It was around the time when 'restrict' was added, which is another
> historical mistake of the committee. In general, every feature they
> added thinking of optimizations (and that includes these two) has
> resulted in a mistake.
>
> > and I so I don't dislike it, And it is
> > standard C.
>
> When the standard clashes with reality and common sense, I'm not sure
> I'd give the standard much credibility.
>
> > I really don't think Linux man-pages is the place to
> > introducing nonstandard, GNU-specific syntax (that people clearly
> > don't understand).
>
> People clearly don't understand [static 2] either.
My understanding is that [static 2] was introduced to facilitate cases
like the following, where an implementation could theoretically
generate code that reads the first four elements together, but would
have to load subsequent elements individually:
int len(int s[static 4])
{
int i = 0;
do
{
if (!s[i]) break; else ++i;
if (!s[i]) break; else ++i;
if (!s[i]) break; else ++i;
if (!s[i]) break; else ++i;
} while (1);
return i;
}
https://godbolt.org/z/ra6zh7Ej3
I have never yet managed to persuade a compiler to optimise such code
differently from a version without 'static 4', and I struggle to
believe it would ever be beneficial to do so. The more obvious case,
where an array bound such as [static 4 * n] potentially enables
speculative loads when unrolling a loop with an early exit, does not
need the compiler to be permitted to generate code that reads beyond
the passed-in array bound.
Christopher
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH] man/: SYNOPSIS: Remove GNU forward-declarations of parameters for lengths of array parameters
2026-10-24 16:16 ` Christopher Bazley
@ 2026-10-24 16:37 ` Alejandro Colomar
2026-10-24 18:11 ` Martin Uecker
0 siblings, 1 reply; 27+ messages in thread
From: Alejandro Colomar @ 2026-10-24 16:37 UTC (permalink / raw)
To: Christopher Bazley
Cc: Michael Kerrisk (man7.org), linux-man, Michael Kerrisk, Sam James,
Carlos O'Donell, Joseph S. Myers, Martin Uecker, corbet
[-- Attachment #1: Type: text/plain, Size: 5684 bytes --]
Hi Chris,
> Date: 2026-10-24 17:16:19+0100
> From: Christopher Bazley <chris.bazley.wg14@gmail.com>
>
> On Sat, Oct 24, 2026 at 2:38 PM Alejandro Colomar
> <alx+linux-man@kernel.org> wrote:
> >
> > > Date: 2026-10-24 09:45:02-0300
> > > From: "Michael Kerrisk (man7.org)" <mtk@man7.org>
> > >
[...]
> > > I was unfamiliar with that syntax, but at least in context it is
> > > immediately understandable,
> >
> > Actually, it is not understandable. [static 2] doesn't mean the same as
> > [2], and this is one historic mistake of the C Committee that I wish had
> > never happened. [static 2] is never what you want (I was tempted to say
> > almost never, but I've never seen a good case for it). Programmers want
> > the meaning of [2].
> >
> > The main differences between [static 2] and [2] are:
> >
> > - [2] means (in GNU C, and in common understanding, but not
> > acknowledged by ISO C) that:
> >
> > - The caller must supply at least 2 elements.
> > - The callee must not access past those 2 elements.
> >
> > - [static 2] means (in ISO C, but ignored by GCC):
> >
> > - The caller must supply at least 2 elements.
> > - The callee is free to access past those 2 elements!!
> > (of course, if there aren't any elements after that, it's UB)
>
> You can, of course, document for the benefit of callers that a
> function does not read past the static array bound.
Comments are bound to be wrong in the future, often near future. It's
better to not use the feature, because it's not necessary. Just use
[2], and ask your compiler to be better than what ISO C requires.
> > - The caller must supply a non-null pointer.
> >
> > The null-pointer issue is nonsense, but we can live with it.
> > The allowance to access past the specified length, that's the real issue
> > with this feature, and why it should not be used at all.
>
> Of the compilers I have tried, only SDCC currently warns about access
> past the specified length, and it does so regardless of whether the
> length is specified using 'static' or not:
>
> int foo(int a[static 2])
> {
> return a[2]; // warning from SDCC
> }
>
> int bar(int a[2])
> {
> return a[2]; // warning from SDCC
> }
>
> https://godbolt.org/z/zf3nPerdn
GCC has some partial diagnostics for out-of-bounds accesses.
alx@debian:~/tmp$ cat oob.c
void five(int a[5]);
void four(int a[4])
{
five(a);
}
void three(int a[static 3])
{
five(a);
}
alx@debian:~/tmp$ gcc -Wall -Wextra -S oob.c
oob.c: In function ‘four’:
oob.c:4:9: warning: ‘five’ accessing 20 bytes in a region of size 16 [-Wstringop-overflow=]
4 | five(a);
| ^~~~~~~
oob.c:4:9: note: referencing argument 1 of type ‘int[5]’
oob.c:1:6: note: in a call to function ‘five’
1 | void five(int a[5]);
| ^~~~
oob.c: In function ‘three’:
oob.c:8:9: warning: ‘five’ accessing 20 bytes in a region of size 12 [-Wstringop-overflow=]
8 | five(a);
| ^~~~~~~
oob.c:8:9: note: referencing argument 1 of type ‘int[5]’
oob.c:1:6: note: in a call to function ‘five’
1 | void five(int a[5]);
| ^~~~
I wish it diagnosed as much as SDCC, but not yet. :)
> (I'm tempted to report the warning produced in the 'static' case as a
> bug, but in reality no warning is a conformance issue, so that
> characterisation is subjective.)
Clearly, not a bug, but rather QoI. ISO C has a bug.
> > The committee was clearly confused when they added this feature.
> > It was around the time when 'restrict' was added, which is another
> > historical mistake of the committee. In general, every feature they
> > added thinking of optimizations (and that includes these two) has
> > resulted in a mistake.
> >
> > > and I so I don't dislike it, And it is
> > > standard C.
> >
> > When the standard clashes with reality and common sense, I'm not sure
> > I'd give the standard much credibility.
> >
> > > I really don't think Linux man-pages is the place to
> > > introducing nonstandard, GNU-specific syntax (that people clearly
> > > don't understand).
> >
> > People clearly don't understand [static 2] either.
>
> My understanding is that [static 2] was introduced to facilitate cases
> like the following, where an implementation could theoretically
> generate code that reads the first four elements together, but would
> have to load subsequent elements individually:
My understanding is tthe same.
>
> int len(int s[static 4])
> {
> int i = 0;
> do
> {
> if (!s[i]) break; else ++i;
> if (!s[i]) break; else ++i;
> if (!s[i]) break; else ++i;
> if (!s[i]) break; else ++i;
> } while (1);
> return i;
> }
> https://godbolt.org/z/ra6zh7Ej3
>
> I have never yet managed to persuade a compiler to optimise such code
> differently from a version without 'static 4', and I struggle to
> believe it would ever be beneficial to do so. The more obvious case,
> where an array bound such as [static 4 * n] potentially enables
> speculative loads when unrolling a loop with an early exit, does not
> need the compiler to be permitted to generate code that reads beyond
> the passed-in array bound.
And indeed, I agree. This seems a case of bad design, wishing that it
might eventually be optimizable, while it wasn't and still isn't, and
also while ignoring the safety issues caused by it. We should just
pretend that the feature doesn't exist.
Cheers,
Alex
--
<https://www.alejandro-colomar.es>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH] man/: SYNOPSIS: Remove GNU forward-declarations of parameters for lengths of array parameters
2026-10-24 16:37 ` Alejandro Colomar
@ 2026-10-24 18:11 ` Martin Uecker
2026-10-25 6:59 ` Alejandro Colomar
0 siblings, 1 reply; 27+ messages in thread
From: Martin Uecker @ 2026-10-24 18:11 UTC (permalink / raw)
To: Alejandro Colomar, Christopher Bazley
Cc: Michael Kerrisk (man7.org), linux-man, Michael Kerrisk, Sam James,
Carlos O'Donell, Joseph S. Myers, corbet
Am Samstag, dem 24.10.2026 um 18:37 +0200 schrieb Alejandro Colomar:
> Hi Chris,
>
> > Date: 2026-10-24 17:16:19+0100
> > From: Christopher Bazley <chris.bazley.wg14@gmail.com>
> >
> > On Sat, Oct 24, 2026 at 2:38 PM Alejandro Colomar
> > <alx+linux-man@kernel.org> wrote:
> > >
> > > > Date: 2026-10-24 09:45:02-0300
> > > > From: "Michael Kerrisk (man7.org)" <mtk@man7.org>
> > > >
> [...]
> > > > I was unfamiliar with that syntax, but at least in context it is
> > > > immediately understandable,
> > >
> > > Actually, it is not understandable. [static 2] doesn't mean the same as
> > > [2], and this is one historic mistake of the C Committee that I wish had
> > > never happened. [static 2] is never what you want (I was tempted to say
> > > almost never, but I've never seen a good case for it). Programmers want
> > > the meaning of [2].
> > >
> > > The main differences between [static 2] and [2] are:
> > >
> > > - [2] means (in GNU C, and in common understanding, but not
> > > acknowledged by ISO C) that:
> > >
> > > - The caller must supply at least 2 elements.
> > > - The callee must not access past those 2 elements.
> > >
> > > - [static 2] means (in ISO C, but ignored by GCC):
> > >
> > > - The caller must supply at least 2 elements.
> > > - The callee is free to access past those 2 elements!!
> > > (of course, if there aren't any elements after that, it's UB)
> >
> > You can, of course, document for the benefit of callers that a
> > function does not read past the static array bound.
>
> Comments are bound to be wrong in the future, often near future. It's
> better to not use the feature, because it's not necessary. Just use
> [2], and ask your compiler to be better than what ISO C requires.
[static ...] implies that the pointer is not null, this is
a standard compliant way to express this (it implies a bit
more as nonnull, but compilers do not support more). Still,
it gives you a real practical security benefit.
void foo(int a[static 3]);
void bar()
{
foo(nullptr);
}
<source>: In function 'bar':
<source>:5:9: warning: argument 1 null where non-null expected [-Wnonnull]
5 | foo(nullptr);
| ^~~
<source>:2:6: note: in a call to function 'foo' declared 'nonnull'
2 | void foo(int a[static 3]);
https://godbolt.org/z/fa4YsWq63
>
> > > - The caller must supply a non-null pointer.
> > >
> > > The null-pointer issue is nonsense, but we can live with it.
> > > The allowance to access past the specified length, that's the real issue
> > > with this feature, and why it should not be used at all.
> >
> > Of the compilers I have tried, only SDCC currently warns about access
> > past the specified length, and it does so regardless of whether the
> > length is specified using 'static' or not:
> >
> > int foo(int a[static 2])
> > {
> > return a[2]; // warning from SDCC
> > }
> >
> > int bar(int a[2])
> > {
> > return a[2]; // warning from SDCC
> > }
> >
> > https://godbolt.org/z/zf3nPerdn
>
> GCC has some partial diagnostics for out-of-bounds accesses.
>
... (example) ...
>
> I wish it diagnosed as much as SDCC, but not yet. :)
The more relevant example is this:
void foo(int n; int a[n], int n);
void bar(int a[4])
{
foo(a, 5);
}
<source>: In function 'bar':
<source>:5:9: warning: 'foo' accessing 20 bytes in a region of size 16 [-Wstringop-overflow=]
5 | foo(a, 5);
| ^~~~~~~~~
<source>:5:9: note: referencing argument 1 of type 'int[]'
<source>:2:6: note: in a call to function 'foo'
2 | void foo(int n; int a[n], int n);
https://godbolt.org/z/hhGYTej49
This has a very real and obvious security benefit.
> ...
> > > The committee was clearly confused when they added this feature.
> > > It was around the time when 'restrict' was added, which is another
> > > historical mistake of the committee. In general, every feature they
> > > added thinking of optimizations (and that includes these two) has
> > > resulted in a mistake.
It was not a mistake, it was a different set of priorities
We now have more users and people interested in safety in
the committee, but powers could easily shift back.
> > >
> > > > and I so I don't dislike it, And it is
> > > > standard C.
> > >
> > > When the standard clashes with reality and common sense, I'm not sure
> > > I'd give the standard much credibility.
> > >
> > > > I really don't think Linux man-pages is the place to
> > > > introducing nonstandard, GNU-specific syntax (that people clearly
> > > > don't understand).
> > >
> > > People clearly don't understand [static 2] either.
> >
> > My understanding is that [static 2] was introduced to facilitate cases
> > like the following, where an implementation could theoretically
> > generate code that reads the first four elements together, but would
> > have to load subsequent elements individually:
>
> My understanding is tthe same.
>
> >
> > int len(int s[static 4])
> > {
> > int i = 0;
> > do
> > {
> > if (!s[i]) break; else ++i;
> > if (!s[i]) break; else ++i;
> > if (!s[i]) break; else ++i;
> > if (!s[i]) break; else ++i;
> > } while (1);
> > return i;
> > }
> > https://godbolt.org/z/ra6zh7Ej3
> >
> > I have never yet managed to persuade a compiler to optimise such code
> > differently from a version without 'static 4', and I struggle to
> > believe it would ever be beneficial to do so. The more obvious case,
> > where an array bound such as [static 4 * n] potentially enables
> > speculative loads when unrolling a loop with an early exit, does not
> > need the compiler to be permitted to generate code that reads beyond
> > the passed-in array bound.
I think the idea of limiting access to the rest of the array did
not occur to them, as this feature was only for optimization.
>
> And indeed, I agree. This seems a case of bad design, wishing that it
> might eventually be optimizable, while it wasn't and still isn't, and
> also while ignoring the safety issues caused by it. We should just
> pretend that the feature doesn't exist.
It would potentially be useful for optimization, but I think there
was a chicken-and-egg problem. Nobody used [static] and then
people worked on instead optimizations more useful for existing code,
so [static] also never become useful for programmers.
Much later it become useful to express non-null pointers.
Martin
>
>
> Cheers,
> Alex
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH] man/: SYNOPSIS: Remove GNU forward-declarations of parameters for lengths of array parameters
2026-10-24 18:11 ` Martin Uecker
@ 2026-10-25 6:59 ` Alejandro Colomar
2026-10-25 7:22 ` Martin Uecker
0 siblings, 1 reply; 27+ messages in thread
From: Alejandro Colomar @ 2026-10-25 6:59 UTC (permalink / raw)
To: Martin Uecker
Cc: Christopher Bazley, Michael Kerrisk (man7.org), linux-man,
Michael Kerrisk, Sam James, Carlos O'Donell, Joseph S. Myers,
corbet
[-- Attachment #1: Type: text/plain, Size: 8203 bytes --]
Hi Martin,
> Date: 2026-10-24 20:11:10+0200
> From: Martin Uecker <uecker@tugraz.at>
>
> Am Samstag, dem 24.10.2026 um 18:37 +0200 schrieb Alejandro Colomar:
> > Hi Chris,
> >
> > > Date: 2026-10-24 17:16:19+0100
> > > From: Christopher Bazley <chris.bazley.wg14@gmail.com>
> > >
> > > On Sat, Oct 24, 2026 at 2:38 PM Alejandro Colomar
> > > <alx+linux-man@kernel.org> wrote:
> > > >
> > > > > Date: 2026-10-24 09:45:02-0300
> > > > > From: "Michael Kerrisk (man7.org)" <mtk@man7.org>
> > > > >
> > [...]
> > > > > I was unfamiliar with that syntax, but at least in context it is
> > > > > immediately understandable,
> > > >
> > > > Actually, it is not understandable. [static 2] doesn't mean the same as
> > > > [2], and this is one historic mistake of the C Committee that I wish had
> > > > never happened. [static 2] is never what you want (I was tempted to say
> > > > almost never, but I've never seen a good case for it). Programmers want
> > > > the meaning of [2].
> > > >
> > > > The main differences between [static 2] and [2] are:
> > > >
> > > > - [2] means (in GNU C, and in common understanding, but not
> > > > acknowledged by ISO C) that:
> > > >
> > > > - The caller must supply at least 2 elements.
> > > > - The callee must not access past those 2 elements.
> > > >
> > > > - [static 2] means (in ISO C, but ignored by GCC):
> > > >
> > > > - The caller must supply at least 2 elements.
> > > > - The callee is free to access past those 2 elements!!
> > > > (of course, if there aren't any elements after that, it's UB)
> > >
> > > You can, of course, document for the benefit of callers that a
> > > function does not read past the static array bound.
> >
> > Comments are bound to be wrong in the future, often near future. It's
> > better to not use the feature, because it's not necessary. Just use
> > [2], and ask your compiler to be better than what ISO C requires.
>
> [static ...] implies that the pointer is not null, this is
> a standard compliant way to express this (it implies a bit
> more as nonnull, but compilers do not support more). Still,
> it gives you a real practical security benefit.
I know you can get usefulness out of it, but the fact that you must
express a bound and that it doesn't mean what everyone would expect it
to mean makes it a broken feature, unless and until we fix the second
bullet by making [static n] mean the same as [[gnu::nonnull]] [n], which
is n3801 <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3801.txt>.
> void foo(int a[static 3]);
> void bar()
> {
> foo(nullptr);
> }
>
> <source>: In function 'bar':
> <source>:5:9: warning: argument 1 null where non-null expected [-Wnonnull]
> 5 | foo(nullptr);
> | ^~~
> <source>:2:6: note: in a call to function 'foo' declared 'nonnull'
> 2 | void foo(int a[static 3]);
>
> https://godbolt.org/z/fa4YsWq63
>
> >
> > > > - The caller must supply a non-null pointer.
> > > >
> > > > The null-pointer issue is nonsense, but we can live with it.
> > > > The allowance to access past the specified length, that's the real issue
> > > > with this feature, and why it should not be used at all.
> > >
> > > Of the compilers I have tried, only SDCC currently warns about access
> > > past the specified length, and it does so regardless of whether the
> > > length is specified using 'static' or not:
> > >
> > > int foo(int a[static 2])
> > > {
> > > return a[2]; // warning from SDCC
> > > }
> > >
> > > int bar(int a[2])
> > > {
> > > return a[2]; // warning from SDCC
> > > }
> > >
> > > https://godbolt.org/z/zf3nPerdn
> >
> > GCC has some partial diagnostics for out-of-bounds accesses.
> >
> ... (example) ...
> >
> > I wish it diagnosed as much as SDCC, but not yet. :)
>
> The more relevant example is this:
>
> void foo(int n; int a[n], int n);
> void bar(int a[4])
> {
> foo(a, 5);
> }
>
> <source>: In function 'bar':
> <source>:5:9: warning: 'foo' accessing 20 bytes in a region of size 16 [-Wstringop-overflow=]
> 5 | foo(a, 5);
> | ^~~~~~~~~
> <source>:5:9: note: referencing argument 1 of type 'int[]'
> <source>:2:6: note: in a call to function 'foo'
> 2 | void foo(int n; int a[n], int n);
>
> https://godbolt.org/z/hhGYTej49
>
> This has a very real and obvious security benefit.
>
> > ...
>
> > > > The committee was clearly confused when they added this feature.
> > > > It was around the time when 'restrict' was added, which is another
> > > > historical mistake of the committee. In general, every feature they
> > > > added thinking of optimizations (and that includes these two) has
> > > > resulted in a mistake.
>
> It was not a mistake, it was a different set of priorities
It was a mistake. They thought it would provide room for optimizations,
but nobody checked whether it was actually useful in the real world.
This seems to me a clear example of a design looking for users, which is
precisely what the C Committee should *not* do.
> We now have more users and people interested in safety in
> the committee, but powers could easily shift back.
>
> > > >
> > > > > and I so I don't dislike it, And it is
> > > > > standard C.
> > > >
> > > > When the standard clashes with reality and common sense, I'm not sure
> > > > I'd give the standard much credibility.
> > > >
> > > > > I really don't think Linux man-pages is the place to
> > > > > introducing nonstandard, GNU-specific syntax (that people clearly
> > > > > don't understand).
> > > >
> > > > People clearly don't understand [static 2] either.
> > >
> > > My understanding is that [static 2] was introduced to facilitate cases
> > > like the following, where an implementation could theoretically
> > > generate code that reads the first four elements together, but would
> > > have to load subsequent elements individually:
> >
> > My understanding is tthe same.
> >
> > >
> > > int len(int s[static 4])
> > > {
> > > int i = 0;
> > > do
> > > {
> > > if (!s[i]) break; else ++i;
> > > if (!s[i]) break; else ++i;
> > > if (!s[i]) break; else ++i;
> > > if (!s[i]) break; else ++i;
> > > } while (1);
> > > return i;
> > > }
> > > https://godbolt.org/z/ra6zh7Ej3
> > >
> > > I have never yet managed to persuade a compiler to optimise such code
> > > differently from a version without 'static 4', and I struggle to
> > > believe it would ever be beneficial to do so. The more obvious case,
> > > where an array bound such as [static 4 * n] potentially enables
> > > speculative loads when unrolling a loop with an early exit, does not
> > > need the compiler to be permitted to generate code that reads beyond
> > > the passed-in array bound.
>
> I think the idea of limiting access to the rest of the array did
> not occur to them, as this feature was only for optimization.
And that's what I call a mistake; a big one.
> > And indeed, I agree. This seems a case of bad design, wishing that it
> > might eventually be optimizable, while it wasn't and still isn't, and
> > also while ignoring the safety issues caused by it. We should just
> > pretend that the feature doesn't exist.
>
> It would potentially be useful for optimization, but I think there
> was a chicken-and-egg problem. Nobody used [static] and then
> people worked on instead optimizations more useful for existing code,
> so [static] also never become useful for programmers.
That's the right approach.
> Much later it become useful to express non-null pointers.
It still hasn't. It will once we get rid of the bound. That is, it
will be useful when one can do [static] or [static *]. And even then,
the fact that it can't be used on function pointers makes it a bad patch
in the language. We need a feature that is consistent.
And we also have the issue that it changes the meaning of the bound.
It's just terrible.
Have a lovely day!
Alex
--
<https://www.alejandro-colomar.es>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH] man/: SYNOPSIS: Remove GNU forward-declarations of parameters for lengths of array parameters
2026-10-25 6:59 ` Alejandro Colomar
@ 2026-10-25 7:22 ` Martin Uecker
2026-10-25 7:38 ` Alejandro Colomar
0 siblings, 1 reply; 27+ messages in thread
From: Martin Uecker @ 2026-10-25 7:22 UTC (permalink / raw)
To: Alejandro Colomar
Cc: Christopher Bazley, Michael Kerrisk (man7.org), linux-man,
Michael Kerrisk, Sam James, Carlos O'Donell, Joseph S. Myers,
corbet
Am Sonntag, dem 25.10.2026 um 07:59 +0100 schrieb Alejandro Colomar:
> Hi Martin,
>
> > Date: 2026-10-24 20:11:10+0200
> > From: Martin Uecker <uecker@tugraz.at>
> >
> > Am Samstag, dem 24.10.2026 um 18:37 +0200 schrieb Alejandro Colomar:
> > > Hi Chris,
> > >
> > > > Date: 2026-10-24 17:16:19+0100
> > > > From: Christopher Bazley <chris.bazley.wg14@gmail.com>
> > > >
> > > > On Sat, Oct 24, 2026 at 2:38 PM Alejandro Colomar
> > > > <alx+linux-man@kernel.org> wrote:
> > > > >
> > > > > > Date: 2026-10-24 09:45:02-0300
> > > > > > From: "Michael Kerrisk (man7.org)" <mtk@man7.org>
> > > > > >
> > > [...]
> > > > > > I was unfamiliar with that syntax, but at least in context it is
> > > > > > immediately understandable,
> > > > >
> > > > > Actually, it is not understandable. [static 2] doesn't mean the same as
> > > > > [2], and this is one historic mistake of the C Committee that I wish had
> > > > > never happened. [static 2] is never what you want (I was tempted to say
> > > > > almost never, but I've never seen a good case for it). Programmers want
> > > > > the meaning of [2].
> > > > >
> > > > > The main differences between [static 2] and [2] are:
> > > > >
> > > > > - [2] means (in GNU C, and in common understanding, but not
> > > > > acknowledged by ISO C) that:
> > > > >
> > > > > - The caller must supply at least 2 elements.
> > > > > - The callee must not access past those 2 elements.
> > > > >
> > > > > - [static 2] means (in ISO C, but ignored by GCC):
> > > > >
> > > > > - The caller must supply at least 2 elements.
> > > > > - The callee is free to access past those 2 elements!!
> > > > > (of course, if there aren't any elements after that, it's UB)
> > > >
> > > > You can, of course, document for the benefit of callers that a
> > > > function does not read past the static array bound.
> > >
> > > Comments are bound to be wrong in the future, often near future. It's
> > > better to not use the feature, because it's not necessary. Just use
> > > [2], and ask your compiler to be better than what ISO C requires.
> >
> > [static ...] implies that the pointer is not null, this is
> > a standard compliant way to express this (it implies a bit
> > more as nonnull, but compilers do not support more). Still,
> > it gives you a real practical security benefit.
>
> I know you can get usefulness out of it, but the fact that you must
> express a bound and that it doesn't mean what everyone would expect it
> to mean makes it a broken feature, unless and until we fix the second
> bullet by making [static n] mean the same as [[gnu::nonnull]] [n], which
> is n3801 <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3801.txt>.
I know. Is this on the agenda?
>
> > void foo(int a[static 3]);
> > void bar()
> > {
> > foo(nullptr);
> > }
> >
> > <source>: In function 'bar':
> > <source>:5:9: warning: argument 1 null where non-null expected [-Wnonnull]
> > 5 | foo(nullptr);
> > | ^~~
> > <source>:2:6: note: in a call to function 'foo' declared 'nonnull'
> > 2 | void foo(int a[static 3]);
> >
> > https://godbolt.org/z/fa4YsWq63
> >
> > >
> > > > > - The caller must supply a non-null pointer.
> > > > >
> > > > > The null-pointer issue is nonsense, but we can live with it.
> > > > > The allowance to access past the specified length, that's the real issue
> > > > > with this feature, and why it should not be used at all.
> > > >
> > > > Of the compilers I have tried, only SDCC currently warns about access
> > > > past the specified length, and it does so regardless of whether the
> > > > length is specified using 'static' or not:
> > > >
> > > > int foo(int a[static 2])
> > > > {
> > > > return a[2]; // warning from SDCC
> > > > }
> > > >
> > > > int bar(int a[2])
> > > > {
> > > > return a[2]; // warning from SDCC
> > > > }
> > > >
> > > > https://godbolt.org/z/zf3nPerdn
> > >
> > > GCC has some partial diagnostics for out-of-bounds accesses.
> > >
> > ... (example) ...
> > >
> > > I wish it diagnosed as much as SDCC, but not yet. :)
> >
> > The more relevant example is this:
> >
> > void foo(int n; int a[n], int n);
> > void bar(int a[4])
> > {
> > foo(a, 5);
> > }
> >
> > <source>: In function 'bar':
> > <source>:5:9: warning: 'foo' accessing 20 bytes in a region of size 16 [-Wstringop-overflow=]
> > 5 | foo(a, 5);
> > | ^~~~~~~~~
> > <source>:5:9: note: referencing argument 1 of type 'int[]'
> > <source>:2:6: note: in a call to function 'foo'
> > 2 | void foo(int n; int a[n], int n);
> >
> > https://godbolt.org/z/hhGYTej49
> >
> > This has a very real and obvious security benefit.
> >
> > > ...
> >
> > > > > The committee was clearly confused when they added this feature.
> > > > > It was around the time when 'restrict' was added, which is another
> > > > > historical mistake of the committee. In general, every feature they
> > > > > added thinking of optimizations (and that includes these two) has
> > > > > resulted in a mistake.
> >
> > It was not a mistake, it was a different set of priorities
>
> It was a mistake. They thought it would provide room for optimizations,
> but nobody checked whether it was actually useful in the real world.
> This seems to me a clear example of a design looking for users, which is
> precisely what the C Committee should *not* do.
I would assume it came from cray and they had real world
use case for this at that time.
>
> > We now have more users and people interested in safety in
> > the committee, but powers could easily shift back.
> >
> > > > >
> > > > > > and I so I don't dislike it, And it is
> > > > > > standard C.
> > > > >
> > > > > When the standard clashes with reality and common sense, I'm not sure
> > > > > I'd give the standard much credibility.
> > > > >
> > > > > > I really don't think Linux man-pages is the place to
> > > > > > introducing nonstandard, GNU-specific syntax (that people clearly
> > > > > > don't understand).
> > > > >
> > > > > People clearly don't understand [static 2] either.
> > > >
> > > > My understanding is that [static 2] was introduced to facilitate cases
> > > > like the following, where an implementation could theoretically
> > > > generate code that reads the first four elements together, but would
> > > > have to load subsequent elements individually:
> > >
> > > My understanding is tthe same.
> > >
> > > >
> > > > int len(int s[static 4])
> > > > {
> > > > int i = 0;
> > > > do
> > > > {
> > > > if (!s[i]) break; else ++i;
> > > > if (!s[i]) break; else ++i;
> > > > if (!s[i]) break; else ++i;
> > > > if (!s[i]) break; else ++i;
> > > > } while (1);
> > > > return i;
> > > > }
> > > > https://godbolt.org/z/ra6zh7Ej3
> > > >
> > > > I have never yet managed to persuade a compiler to optimise such code
> > > > differently from a version without 'static 4', and I struggle to
> > > > believe it would ever be beneficial to do so. The more obvious case,
> > > > where an array bound such as [static 4 * n] potentially enables
> > > > speculative loads when unrolling a loop with an early exit, does not
> > > > need the compiler to be permitted to generate code that reads beyond
> > > > the passed-in array bound.
> >
> > I think the idea of limiting access to the rest of the array did
> > not occur to them, as this feature was only for optimization.
>
> And that's what I call a mistake; a big one.
>
> > > And indeed, I agree. This seems a case of bad design, wishing that it
> > > might eventually be optimizable, while it wasn't and still isn't, and
> > > also while ignoring the safety issues caused by it. We should just
> > > pretend that the feature doesn't exist.
> >
> > It would potentially be useful for optimization, but I think there
> > was a chicken-and-egg problem. Nobody used [static] and then
> > people worked on instead optimizations more useful for existing code,
> > so [static] also never become useful for programmers.
>
> That's the right approach.
>
> > Much later it become useful to express non-null pointers.
>
> It still hasn't. It will once we get rid of the bound. That is, it
> will be useful when one can do [static] or [static *]. And even then,
> the fact that it can't be used on function pointers makes it a bad patch
> in the language. We need a feature that is consistent.
Yes, but we do not even have a proposal and [static 1] exists today.
>
> And we also have the issue that it changes the meaning of the bound.
> It's just terrible.
The bound in [1] has no meaning in parameters, so [static 1] changes
the meaning only in a sense that that it has a stricter meaning
that is still only a subset of what we want.
Martin
>
>
> Have a lovely day!
> Alex
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH] man/: SYNOPSIS: Remove GNU forward-declarations of parameters for lengths of array parameters
2026-10-25 7:22 ` Martin Uecker
@ 2026-10-25 7:38 ` Alejandro Colomar
2026-10-25 8:29 ` G. Branden Robinson
2026-10-25 8:40 ` Martin Uecker
0 siblings, 2 replies; 27+ messages in thread
From: Alejandro Colomar @ 2026-10-25 7:38 UTC (permalink / raw)
To: Martin Uecker
Cc: Christopher Bazley, Michael Kerrisk (man7.org), linux-man,
Michael Kerrisk, Sam James, Carlos O'Donell, Joseph S. Myers,
corbet
[-- Attachment #1: Type: text/plain, Size: 4556 bytes --]
Hi Martin,
> Date: 2026-10-25 08:22:23+0100
> From: Martin Uecker <uecker@tugraz.at>
>
> Am Sonntag, dem 25.10.2026 um 07:59 +0100 schrieb Alejandro Colomar:
> > Hi Martin,
> >
> > > Date: 2026-10-24 20:11:10+0200
> > > From: Martin Uecker <uecker@tugraz.at>
> > >
[...]
> > > [static ...] implies that the pointer is not null, this is
> > > a standard compliant way to express this (it implies a bit
> > > more as nonnull, but compilers do not support more). Still,
> > > it gives you a real practical security benefit.
> >
> > I know you can get usefulness out of it, but the fact that you must
> > express a bound and that it doesn't mean what everyone would expect it
> > to mean makes it a broken feature, unless and until we fix the second
> > bullet by making [static n] mean the same as [[gnu::nonnull]] [n], which
> > is n3801 <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3801.txt>.
>
> I know. Is this on the agenda?
No; it has wording issues pointed out by Joseph, and I don't have the
time or energy to address them at the moment. See [SC22WG14.36403] in
the mailing list.
Feel free to take over the paper if you have a good idea for those.
I plan to come back to it, but not this year.
[...]
> > > > > > The committee was clearly confused when they added this feature.
> > > > > > It was around the time when 'restrict' was added, which is another
> > > > > > historical mistake of the committee. In general, every feature they
> > > > > > added thinking of optimizations (and that includes these two) has
> > > > > > resulted in a mistake.
> > >
> > > It was not a mistake, it was a different set of priorities
> >
> > It was a mistake. They thought it would provide room for optimizations,
> > but nobody checked whether it was actually useful in the real world.
> > This seems to me a clear example of a design looking for users, which is
> > precisely what the C Committee should *not* do.
>
> I would assume it came from cray and they had real world
> use case for this at that time.
What is 'cray'?
[...]
> > > I think the idea of limiting access to the rest of the array did
> > > not occur to them, as this feature was only for optimization.
> >
> > And that's what I call a mistake; a big one.
> >
> > > > And indeed, I agree. This seems a case of bad design, wishing that it
> > > > might eventually be optimizable, while it wasn't and still isn't, and
> > > > also while ignoring the safety issues caused by it. We should just
> > > > pretend that the feature doesn't exist.
> > >
> > > It would potentially be useful for optimization, but I think there
> > > was a chicken-and-egg problem. Nobody used [static] and then
> > > people worked on instead optimizations more useful for existing code,
> > > so [static] also never become useful for programmers.
> >
> > That's the right approach.
> >
> > > Much later it become useful to express non-null pointers.
> >
> > It still hasn't. It will once we get rid of the bound. That is, it
> > will be useful when one can do [static] or [static *]. And even then,
> > the fact that it can't be used on function pointers makes it a bad patch
> > in the language. We need a feature that is consistent.
>
> Yes, but we do not even have a proposal and [static 1] exists today.
Actually, we do have one: n3803.
<https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3803.txt>
The wording on this one is good. I think I forgot some trivial
duplication of the diff for both the non-abstract and the abstract
declarators, but I can fix that when I arrive home, so we could have it
in time for the next meeting.
> >
> > And we also have the issue that it changes the meaning of the bound.
> > It's just terrible.
>
> The bound in [1] has no meaning in parameters,
This is not true. ISO C is just toilet paper in this regard.
It has a meaning in SDCC and GCC, and every programmer that ever wrote
[1] assigned a meaning to it. Moreover, I'm using [1] myself to express
pointers to exactly 1 element.
> so [static 1] changes
> the meaning only in a sense that that it has a stricter meaning
> that is still only a subset of what we want.
This is just not true. The standard is meaningless when it clashes with
reality and common sense. As Capt. Barbossa would say, "the [standard]
is more what you'd call "guidelines" than actual rules. Welcome aboard
the Black Pearl, Miss Turner!"
Cheers,
Alex
--
<https://www.alejandro-colomar.es>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] man/: SYNOPSIS: Remove GNU forward-declarations of parameters for lengths of array parameters
2026-10-25 7:38 ` Alejandro Colomar
@ 2026-10-25 8:29 ` G. Branden Robinson
2026-10-25 8:40 ` Martin Uecker
1 sibling, 0 replies; 27+ messages in thread
From: G. Branden Robinson @ 2026-10-25 8:29 UTC (permalink / raw)
To: Alejandro Colomar
Cc: Martin Uecker, Christopher Bazley, Michael Kerrisk (man7.org),
linux-man, Michael Kerrisk, Sam James, Carlos O'Donell,
Joseph S. Myers, corbet
[-- Attachment #1: Type: text/plain, Size: 523 bytes --]
At 2026-10-25T08:38:55+0100, Alejandro Colomar wrote:
> > Date: 2026-10-25 08:22:23+0100
> > From: Martin Uecker <uecker@tugraz.at>
> > I would assume it came from cray and they had real world
> > use case for this at that time.
>
> What is 'cray'?
Seymour Cray, founder of Cray Research, commonly known as "the father of
supercomputing".
The Wikipedia articles on him and/or the company will get you up to
speed.
Like John Nash, he might have lived longer but for careless drivers.
Regards,
Branden
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] man/: SYNOPSIS: Remove GNU forward-declarations of parameters for lengths of array parameters
2026-10-25 7:38 ` Alejandro Colomar
2026-10-25 8:29 ` G. Branden Robinson
@ 2026-10-25 8:40 ` Martin Uecker
2026-10-25 8:57 ` Alejandro Colomar
1 sibling, 1 reply; 27+ messages in thread
From: Martin Uecker @ 2026-10-25 8:40 UTC (permalink / raw)
To: Alejandro Colomar
Cc: Christopher Bazley, Michael Kerrisk (man7.org), linux-man,
Michael Kerrisk, Sam James, Carlos O'Donell, Joseph S. Myers,
corbet
Am Sonntag, dem 25.10.2026 um 08:38 +0100 schrieb Alejandro Colomar:
> Hi Martin,
>
> >
...
> > >
> > > > Much later it become useful to express non-null pointers.
> > >
> > > It still hasn't. It will once we get rid of the bound. That is, it
> > > will be useful when one can do [static] or [static *]. And even then,
> > > the fact that it can't be used on function pointers makes it a bad patch
> > > in the language. We need a feature that is consistent.
> >
> > Yes, but we do not even have a proposal and [static 1] exists today.
>
> Actually, we do have one: n3803.
> <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3803.txt>
>
> The wording on this one is good. I think I forgot some trivial
> duplication of the diff for both the non-abstract and the abstract
> declarators, but I can fix that when I arrive home, so we could have it
> in time for the next meeting.
Yes, please. But this would also not work for function pointer,
so I thought you meant something new.
>
> > >
> > > And we also have the issue that it changes the meaning of the bound.
> > > It's just terrible.
> >
> > The bound in [1] has no meaning in parameters,
>
> This is not true. ISO C is just toilet paper in this regard.
> It has a meaning in SDCC and GCC, and every programmer that ever wrote
> [1] assigned a meaning to it. Moreover, I'm using [1] myself to express
> pointers to exactly 1 element.
In GCC [static n] and [n] have the same meaning, except
that [static] additionally implies that the pointer is not null.
I have worked on this, so please assume I know this.
In ISO C it is as I said, [n] has no meaning and [static n]
is a strict subset of what we want.
So I am really confused about what you are trying to tell me.
Martin
>
> > so [static 1] changes
> > the meaning only in a sense that that it has a stricter meaning
> > that is still only a subset of what we want.
>
> This is just not true. The standard is meaningless when it clashes with
> reality and common sense. As Capt. Barbossa would say, "the [standard]
> is more what you'd call "guidelines" than actual rules. Welcome aboard
> the Black Pearl, Miss Turner!"
>
>
> Cheers,
> Alex
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] man/: SYNOPSIS: Remove GNU forward-declarations of parameters for lengths of array parameters
2026-10-25 8:40 ` Martin Uecker
@ 2026-10-25 8:57 ` Alejandro Colomar
2026-10-25 9:05 ` Martin Uecker
0 siblings, 1 reply; 27+ messages in thread
From: Alejandro Colomar @ 2026-10-25 8:57 UTC (permalink / raw)
To: Martin Uecker
Cc: Christopher Bazley, Michael Kerrisk (man7.org), linux-man,
Michael Kerrisk, Sam James, Carlos O'Donell, Joseph S. Myers,
corbet
[-- Attachment #1: Type: text/plain, Size: 2163 bytes --]
Hi Martin,
> Date: 2026-10-25 09:40:52+0100
> From: Martin Uecker <uecker@tugraz.at>
>
> Am Sonntag, dem 25.10.2026 um 08:38 +0100 schrieb Alejandro Colomar:
[...]
> > > Yes, but we do not even have a proposal and [static 1] exists today.
> >
> > Actually, we do have one: n3803.
> > <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3803.txt>
> >
> > The wording on this one is good. I think I forgot some trivial
> > duplication of the diff for both the non-abstract and the abstract
> > declarators, but I can fix that when I arrive home, so we could have it
> > in time for the next meeting.
>
> Yes, please. But this would also not work for function pointer,
> so I thought you meant something new.
Done. I've asked Dan for a number, and sent the draft to the mailing
list.
> > > > And we also have the issue that it changes the meaning of the bound.
> > > > It's just terrible.
> > >
> > > The bound in [1] has no meaning in parameters,
> >
> > This is not true. ISO C is just toilet paper in this regard.
> > It has a meaning in SDCC and GCC, and every programmer that ever wrote
> > [1] assigned a meaning to it. Moreover, I'm using [1] myself to express
> > pointers to exactly 1 element.
>
> In GCC [static n] and [n] have the same meaning, except
> that [static] additionally implies that the pointer is not null.
> I have worked on this, so please assume I know this.
Indeed, I know you know.
> In ISO C it is as I said, [n] has no meaning and [static n]
> is a strict subset of what we want.
And I insist that ISO C should be ignored. It doesn't matter what ISO C
says about it, and your statement that [1] has no meaning in parameters
is giving it too much credibility.
> So I am really confused about what you are trying to tell me.
I'm trying to say that [1] has a meaning, even outside of GCC. Every
programmer that ever wrote [n] meant the obvious thing. The fact that
ISO C ignores this shouldn't be an excuse to claim that [static n]
doesn't change the meaning, because it is a de-facto change of meaning.
Cheers,
Alex
--
<https://www.alejandro-colomar.es>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] man/: SYNOPSIS: Remove GNU forward-declarations of parameters for lengths of array parameters
2026-10-25 8:57 ` Alejandro Colomar
@ 2026-10-25 9:05 ` Martin Uecker
0 siblings, 0 replies; 27+ messages in thread
From: Martin Uecker @ 2026-10-25 9:05 UTC (permalink / raw)
To: Alejandro Colomar
Cc: Christopher Bazley, Michael Kerrisk (man7.org), linux-man,
Michael Kerrisk, Sam James, Carlos O'Donell, Joseph S. Myers,
corbet
Thanks. I think we are on the same page on this.
And thanks for pushing this forward.
Martin
Am Sonntag, dem 25.10.2026 um 09:57 +0100 schrieb Alejandro Colomar:
> Hi Martin,
>
> > Date: 2026-10-25 09:40:52+0100
> > From: Martin Uecker <uecker@tugraz.at>
> >
> > Am Sonntag, dem 25.10.2026 um 08:38 +0100 schrieb Alejandro Colomar:
> [...]
> > > > Yes, but we do not even have a proposal and [static 1] exists today.
> > >
> > > Actually, we do have one: n3803.
> > > <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3803.txt>
> > >
> > > The wording on this one is good. I think I forgot some trivial
> > > duplication of the diff for both the non-abstract and the abstract
> > > declarators, but I can fix that when I arrive home, so we could have it
> > > in time for the next meeting.
> >
> > Yes, please. But this would also not work for function pointer,
> > so I thought you meant something new.
>
> Done. I've asked Dan for a number, and sent the draft to the mailing
> list.
>
> > > > > And we also have the issue that it changes the meaning of the bound.
> > > > > It's just terrible.
> > > >
> > > > The bound in [1] has no meaning in parameters,
> > >
> > > This is not true. ISO C is just toilet paper in this regard.
> > > It has a meaning in SDCC and GCC, and every programmer that ever wrote
> > > [1] assigned a meaning to it. Moreover, I'm using [1] myself to express
> > > pointers to exactly 1 element.
> >
> > In GCC [static n] and [n] have the same meaning, except
> > that [static] additionally implies that the pointer is not null.
> > I have worked on this, so please assume I know this.
>
> Indeed, I know you know.
>
> > In ISO C it is as I said, [n] has no meaning and [static n]
> > is a strict subset of what we want.
>
> And I insist that ISO C should be ignored. It doesn't matter what ISO C
> says about it, and your statement that [1] has no meaning in parameters
> is giving it too much credibility.
>
> > So I am really confused about what you are trying to tell me.
>
> I'm trying to say that [1] has a meaning, even outside of GCC. Every
> programmer that ever wrote [n] meant the obvious thing. The fact that
> ISO C ignores this shouldn't be an excuse to claim that [static n]
> doesn't change the meaning, because it is a de-facto change of meaning.
>
>
> Cheers,
> Alex
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] man/: SYNOPSIS: Remove GNU forward-declarations of parameters for lengths of array parameters
2026-10-22 19:54 ` Alejandro Colomar
2026-10-23 11:53 ` Michael Kerrisk (man7.org)
@ 2026-10-23 12:11 ` Alejandro Colomar
1 sibling, 0 replies; 27+ messages in thread
From: Alejandro Colomar @ 2026-10-23 12:11 UTC (permalink / raw)
To: Christopher Bazley
Cc: linux-man, Michael Kerrisk, Sam James, Carlos O'Donell,
Joseph S. Myers, Martin Uecker
[-- Attachment #1: Type: text/plain, Size: 1136 bytes --]
> Date: 2026-10-22 21:54:09+0200
> From: Alejandro Colomar <alx+linux-man@kernel.org>
>
> > Date: 2026-10-22 18:29:31+0100
> > From: Christopher Bazley <chris.bazley.wg14@gmail.com>
> >
[...]
> > but the fact that there are no useful ISO C
> > semantics for parameters of pointer type declared using array syntax
> > weakens my concern. (If the parameters actually had variably-modified types
> > then the change would be far worse, from my point of view, because the
> > parameter types would no longer be expressed correctly.)
>
> We don't care about what ISO C says. GNU C clearly assigns semantics to
> array parameters, and that means we have to be careful about them here.
> If this can result in sanitizers breaking code, it is something to be
> careful about. Moreover, I hope ISO C eventually catches up.
Moreover, there's GCC discussing at the moment a patch of mine to have
_Countof(parameter) work, which would be an even larger risk: it would
produce different values in code, and not just sanitizers aborting some
program.
Have a lovely day!
Alex
--
<https://www.alejandro-colomar.es>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] man/: SYNOPSIS: Remove GNU forward-declarations of parameters for lengths of array parameters
2026-10-22 16:44 [PATCH] man/: SYNOPSIS: Remove GNU forward-declarations of parameters for lengths of array parameters Alejandro Colomar
` (2 preceding siblings ...)
[not found] ` <CAEHU8x9jET+vcrR0NpDz6t57egQG8TZqx5XtV52srH9ZRvdxSQ@mail.gmail.com>
@ 2026-10-22 22:03 ` Mark Harris
2026-10-23 9:43 ` Alejandro Colomar
2026-10-24 7:53 ` Martin Uecker
3 siblings, 2 replies; 27+ messages in thread
From: Mark Harris @ 2026-10-22 22:03 UTC (permalink / raw)
To: Alejandro Colomar
Cc: linux-man, Alejandro Colomar, Michael Kerrisk, Christopher Bazley,
Sam James, Carlos O'Donell, Joseph S. Myers, Martin Uecker
Alejandro Colomar wrote:
>
> From: Alejandro Colomar <alx+linux-man@kernel.org>
>
> From: Alejandro Colomar <alx@kernel.org>
>
> I'm not fully convinced of this patch. But I'm open to being convinced.
> I've written the patch, as Michael asked me to do, but am willing to
> hear everyone's opinion before applying the patch.
>
> As Michael reminded me recently, and as I've defended in other cases, it
> is true that the SYNOPSIS of the manual pages does not need to be
> strictly valid C. It only needs to be useful enough for readers to
> understand the interface. Thus, if using lengths without declaring them
> would improve the usefulness of the documentation, even if becoming
> invalid C, it would be okay.
>
> However, I still have doubts, because this change comes with risks:
>
> Programmers might think it is valid C to refer to parameters that have
> not been declared yet, and use that in their code, and if they are
> unlucky, it might compile for them, which might result in UB at some
> point.
>
> One valid point is that this is rather unlikely to happen, and most of
> the time it will just result in a compiler error, because no global
> variables with the name of the parameter exist.
>
> However, with local (nested) functions, this might be easier to happen,
> as variables declared in the outer function are more likely to share a
> name with a length parameter. Given that the C Committee is working
> hard to standardize local functions, it might be a very bad idea to have
> this combination of events going on.
>
> Concerns that have been raised against using the GNU C syntax in the
> manual pages:
>
> Very very few programmers know this syntax, and thus they are confused
> when reading it for the first time.
>
> This is obviously true. However, this is true of any innovative syntax.
> We should consider whether the confusion is dangerous or not, and
> whether programmers can learn it easily or not.
>
> I believe once you've been exposed to this syntax, after some research,
> or asking the right people, one would easily learn to read it, and then
> we'd have overcome the issue. I don't think the syntax is inherently
> difficult to understand once you've seen the documentation and seen it
> a few times.
>
> Also, this syntax is not very dangerous: a programmer thinking
> that a forward declaration is actually a normal parameter will pass a
> wrong number of arguments to the function, and thus will have compiler
> errors. This syntax is quite robust, as it requires several bugs to
> happen in the same code to pass compilation silently. If one replaces
> ';' with ',', the parameter will be declared twice, which is an error.
> If one renames a forward declaration, it will not match a parameter, and
> will result in a compiler error. Only if both mistakes happen at once,
> the compilation would pass, but then the call sites would also have to
> match the bogus declaration. And also, the function definition would
> have unused parameters, which would trigger diagnostics. So, concerning
> safety, this feature is not very dangerous, even if used by someone who
> is very confused.
>
> Do we think programmers are unable to ever learn this new syntax?
> Are we ready to accept the risks of using the dangerous invalid syntax,
> but which is more intuitive to programmers?
>
> Reported-by: Michael Kerrisk <mtk.manpages@gmail.com>
> Not-yet-Signed-off-by: Alejandro Colomar <alx@kernel.org>
> ---
The man pages are frequently used when seeing a call to an unfamiliar
function, to understand what the function expects and what it is doing
with those arguments. The arguments in the call are matched to the
synopsis by order, not by name, so for example a person questioning
the first argument would naturally be looking at the first thing after
the "(" to find out what is expected there.
A person that is reading the description, where it refers to the
arguments by name, needs to convert that name to the argument number
in order to match it to the arguments in the actual call. The natural
way to do that is to count the argument names in the synopsis (at
least those not preceded by an unterminated bracket or comment) and
stop when that name is found. For example if that is the first
argument name after the "(" in the synopsis then it would be natural
to conclude that it matches the first argument to the call, and not
continue scanning to see if there is another occurrence of the same
argument name.
So I agree with Michael that this change is a good one to make the man
pages less confusing. Thanks for creating the change.
- Mark
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH] man/: SYNOPSIS: Remove GNU forward-declarations of parameters for lengths of array parameters
2026-10-22 22:03 ` Mark Harris
@ 2026-10-23 9:43 ` Alejandro Colomar
2026-10-23 19:32 ` Mark Harris
2026-10-24 7:53 ` Martin Uecker
1 sibling, 1 reply; 27+ messages in thread
From: Alejandro Colomar @ 2026-10-23 9:43 UTC (permalink / raw)
To: Mark Harris
Cc: linux-man, Michael Kerrisk, Christopher Bazley, Sam James,
Carlos O'Donell, Joseph S. Myers, Martin Uecker
[-- Attachment #1: Type: text/plain, Size: 1986 bytes --]
Hi Mark,
> Date: 2026-10-22 15:03:37-0700
> From: Mark Harris <mark.hsj@gmail.com>
>
[...]
>
> The man pages are frequently used when seeing a call to an unfamiliar
> function, to understand what the function expects and what it is doing
> with those arguments. The arguments in the call are matched to the
> synopsis by order, not by name, so for example a person questioning
> the first argument would naturally be looking at the first thing after
> the "(" to find out what is expected there.
>
> A person that is reading the description, where it refers to the
> arguments by name, needs to convert that name to the argument number
> in order to match it to the arguments in the actual call. The natural
> way to do that is to count the argument names in the synopsis (at
> least those not preceded by an unterminated bracket or comment) and
> stop when that name is found. For example if that is the first
> argument name after the "(" in the synopsis then it would be natural
> to conclude that it matches the first argument to the call, and not
> continue scanning to see if there is another occurrence of the same
> argument name.
That's a valid concern, but most often the first argument will be of
a different and incompatible type (they tend to be pointers, which is
the reason we need the forward declaration in the first place), and thus
such a mistake in the understanding of the order of arguments will
result in a compiler error, which is a relatively mild problem.
You didn't take into account my other concerns, though. I'd like to
hear your opinion about the concerns that letting users think that is
valid C might lead to them writing code that has UB (or logic errors).
> So I agree with Michael that this change is a good one to make the man
> pages less confusing. Thanks for creating the change.
Thanks for your feedback!
>
> - Mark
Have a lovely day!
Alex
--
<https://www.alejandro-colomar.es>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH] man/: SYNOPSIS: Remove GNU forward-declarations of parameters for lengths of array parameters
2026-10-23 9:43 ` Alejandro Colomar
@ 2026-10-23 19:32 ` Mark Harris
2026-10-23 20:06 ` Alejandro Colomar
0 siblings, 1 reply; 27+ messages in thread
From: Mark Harris @ 2026-10-23 19:32 UTC (permalink / raw)
To: Alejandro Colomar
Cc: linux-man, Michael Kerrisk, Christopher Bazley, Sam James,
Carlos O'Donell, Joseph S. Myers, Martin Uecker
Alejandro Colomar wrote:
>
> Hi Mark,
>
> > Date: 2026-10-22 15:03:37-0700
> > From: Mark Harris <mark.hsj@gmail.com>
> >
> [...]
> >
> > The man pages are frequently used when seeing a call to an unfamiliar
> > function, to understand what the function expects and what it is doing
> > with those arguments. The arguments in the call are matched to the
> > synopsis by order, not by name, so for example a person questioning
> > the first argument would naturally be looking at the first thing after
> > the "(" to find out what is expected there.
> >
> > A person that is reading the description, where it refers to the
> > arguments by name, needs to convert that name to the argument number
> > in order to match it to the arguments in the actual call. The natural
> > way to do that is to count the argument names in the synopsis (at
> > least those not preceded by an unterminated bracket or comment) and
> > stop when that name is found. For example if that is the first
> > argument name after the "(" in the synopsis then it would be natural
> > to conclude that it matches the first argument to the call, and not
> > continue scanning to see if there is another occurrence of the same
> > argument name.
>
> That's a valid concern, but most often the first argument will be of
> a different and incompatible type (they tend to be pointers, which is
> the reason we need the forward declaration in the first place), and thus
> such a mistake in the understanding of the order of arguments will
> result in a compiler error, which is a relatively mild problem.
I am not talking about someone writing new code that they will then
try to compile at some point, I am talking about someone trying to
understand or debug existing code.
For example, they may be looking for all code that writes to some
particular data or performs some particular operation on it. They see
that a pointer to the data is passed to various functions, and then
for any unfamiliar function they may quickly check the man page to
determine whether they can rule out this call as unrelated. Because C
function calls use positional syntax but the man pages describe the
function of the arguments using argument names, they will have to
count the arguments in the synopsis, which will give them an argument
name, and then they can search for the argument name in the
description to find out what the function does with that argument. If
the counting is complicated they may end up with the wrong argument
name and determine that the function does not perform any action of
interest on this argument, resulting in failure to complete the task.
Even long-time C users may be foiled by the forward declaration, but
it is possible that the person does not even know C; perhaps they are
calling into this C library from another language binding and are
trying to debug what is happening. The man pages should do what it
can to help them, not throw monkey wrenches in their path.
>
> You didn't take into account my other concerns, though. I'd like to
> hear your opinion about the concerns that letting users think that is
> valid C might lead to them writing code that has UB (or logic errors).
An error in thinking that this is valid C syntax doesn't impact anyone
trying to understand existing code, so I don't see the concerns as
comparable.
If someone adds this in their own C code, and it has not been adopted
as valid ISO C or as a compiler extension, then it is extremely likely
to result in a compiler error. If a likely compiler error was good
enough for you when someone writes the arguments in the wrong order in
their code due to confusion over the syntax, then I don't see why it
wouldn't be satisfactory in this case where a compiler error is even
more likely. In both cases there is a chance that it will be accepted
and do the wrong thing.
- Mark
>
> > So I agree with Michael that this change is a good one to make the man
> > pages less confusing. Thanks for creating the change.
>
> Thanks for your feedback!
>
> >
> > - Mark
>
>
> Have a lovely day!
> Alex
>
> --
> <https://www.alejandro-colomar.es>
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH] man/: SYNOPSIS: Remove GNU forward-declarations of parameters for lengths of array parameters
2026-10-23 19:32 ` Mark Harris
@ 2026-10-23 20:06 ` Alejandro Colomar
0 siblings, 0 replies; 27+ messages in thread
From: Alejandro Colomar @ 2026-10-23 20:06 UTC (permalink / raw)
To: Mark Harris
Cc: linux-man, Michael Kerrisk, Christopher Bazley, Sam James,
Carlos O'Donell, Joseph S. Myers, Martin Uecker
[-- Attachment #1: Type: text/plain, Size: 2525 bytes --]
Hi Mark,
> Date: 2026-10-23 12:32:37-0700
> From: Mark Harris <mark.hsj@gmail.com>
>
[...]
>
> I am not talking about someone writing new code that they will then
> try to compile at some point, I am talking about someone trying to
> understand or debug existing code.
>
[...]
> trying to debug what is happening. The man pages should do what it
> can to help them, not throw monkey wrenches in their path.
I see your concern.
> > You didn't take into account my other concerns, though. I'd like to
> > hear your opinion about the concerns that letting users think that is
> > valid C might lead to them writing code that has UB (or logic errors).
>
> An error in thinking that this is valid C syntax doesn't impact anyone
> trying to understand existing code, so I don't see the concerns as
> comparable.
It is actually valid syntax already. It doesn't have the meaning that
we would be using for it, but it's valid syntax.
int n = 42;
int f(char a[n], int n);
f(a, 7);
The array parameter is declared to have 42 elements, regardless of the
7 used at call site.
> If someone adds this in their own C code, and it has not been adopted
> as valid ISO C
The code above is valid C89, and it doesn't mean what one would
intuitively think it means. That's my concern. This is a source of
bugs.
Future extensions to the language will make that even more dangerous, by
making it more likely to compile:
alx@debian:~/tmp$ cat param.c
int
main(void)
{
int n = 42;
int f(char a[n], int n)
{
return _Countof(a);
}
char s[] = "foo";
return f(s, _Countof(s));
}
alx@debian:~/tmp$ /opt/local/gnu/gcc/cap/bin/gcc -Wall -Wextra param.c
param.c: In function ‘f’:
param.c:6:30: warning: unused parameter ‘n’ [-Wunused-parameter]
6 | int f(char a[n], int n)
| ~~~~^
alx@debian:~/tmp$ ./a.out; echo $?
42
> or as a compiler extension, then it is extremely likely
> to result in a compiler error. If a likely compiler error was good
> enough for you when someone writes the arguments in the wrong order in
> their code due to confusion over the syntax, then I don't see why it
> wouldn't be satisfactory in this case where a compiler error is even
> more likely. In both cases there is a chance that it will be accepted
> and do the wrong thing.
This analysis is wrong. See above.
Have a lovely night!
Alex
--
<https://www.alejandro-colomar.es>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] man/: SYNOPSIS: Remove GNU forward-declarations of parameters for lengths of array parameters
2026-10-22 22:03 ` Mark Harris
2026-10-23 9:43 ` Alejandro Colomar
@ 2026-10-24 7:53 ` Martin Uecker
1 sibling, 0 replies; 27+ messages in thread
From: Martin Uecker @ 2026-10-24 7:53 UTC (permalink / raw)
To: Mark Harris, Alejandro Colomar
Cc: linux-man, Alejandro Colomar, Michael Kerrisk, Christopher Bazley,
Sam James, Carlos O'Donell, Joseph S. Myers
I personally do not quite see much risk for mistakes
either way.
I think the more imporant question is whether
man pages will use its role to help make the C ecosystem
safer by educating people about forward declarations as
a tool that directly improves safety of C code, or whether
it wants to remove any friction for users that simply
want to get a job done. Both a valid positions.
In light of the fact that safety is a critical problem
for old-style C code, I personally would be more happy if
it prioritizes safety over use convenience, but this is
not my decision.
Martin
Am Donnerstag, dem 22.10.2026 um 15:03 -0700 schrieb Mark Harris:
> Alejandro Colomar wrote:
> >
> > From: Alejandro Colomar <alx+linux-man@kernel.org>
> >
> > From: Alejandro Colomar <alx@kernel.org>
> >
> > I'm not fully convinced of this patch. But I'm open to being convinced.
> > I've written the patch, as Michael asked me to do, but am willing to
> > hear everyone's opinion before applying the patch.
> >
> > As Michael reminded me recently, and as I've defended in other cases, it
> > is true that the SYNOPSIS of the manual pages does not need to be
> > strictly valid C. It only needs to be useful enough for readers to
> > understand the interface. Thus, if using lengths without declaring them
> > would improve the usefulness of the documentation, even if becoming
> > invalid C, it would be okay.
> >
> > However, I still have doubts, because this change comes with risks:
> >
> > Programmers might think it is valid C to refer to parameters that have
> > not been declared yet, and use that in their code, and if they are
> > unlucky, it might compile for them, which might result in UB at some
> > point.
> >
> > One valid point is that this is rather unlikely to happen, and most of
> > the time it will just result in a compiler error, because no global
> > variables with the name of the parameter exist.
> >
> > However, with local (nested) functions, this might be easier to happen,
> > as variables declared in the outer function are more likely to share a
> > name with a length parameter. Given that the C Committee is working
> > hard to standardize local functions, it might be a very bad idea to have
> > this combination of events going on.
> >
> > Concerns that have been raised against using the GNU C syntax in the
> > manual pages:
> >
> > Very very few programmers know this syntax, and thus they are confused
> > when reading it for the first time.
> >
> > This is obviously true. However, this is true of any innovative syntax.
> > We should consider whether the confusion is dangerous or not, and
> > whether programmers can learn it easily or not.
> >
> > I believe once you've been exposed to this syntax, after some research,
> > or asking the right people, one would easily learn to read it, and then
> > we'd have overcome the issue. I don't think the syntax is inherently
> > difficult to understand once you've seen the documentation and seen it
> > a few times.
> >
> > Also, this syntax is not very dangerous: a programmer thinking
> > that a forward declaration is actually a normal parameter will pass a
> > wrong number of arguments to the function, and thus will have compiler
> > errors. This syntax is quite robust, as it requires several bugs to
> > happen in the same code to pass compilation silently. If one replaces
> > ';' with ',', the parameter will be declared twice, which is an error.
> > If one renames a forward declaration, it will not match a parameter, and
> > will result in a compiler error. Only if both mistakes happen at once,
> > the compilation would pass, but then the call sites would also have to
> > match the bogus declaration. And also, the function definition would
> > have unused parameters, which would trigger diagnostics. So, concerning
> > safety, this feature is not very dangerous, even if used by someone who
> > is very confused.
> >
> > Do we think programmers are unable to ever learn this new syntax?
> > Are we ready to accept the risks of using the dangerous invalid syntax,
> > but which is more intuitive to programmers?
> >
> > Reported-by: Michael Kerrisk <mtk.manpages@gmail.com>
> > Not-yet-Signed-off-by: Alejandro Colomar <alx@kernel.org>
> > ---
>
> The man pages are frequently used when seeing a call to an unfamiliar
> function, to understand what the function expects and what it is doing
> with those arguments. The arguments in the call are matched to the
> synopsis by order, not by name, so for example a person questioning
> the first argument would naturally be looking at the first thing after
> the "(" to find out what is expected there.
>
> A person that is reading the description, where it refers to the
> arguments by name, needs to convert that name to the argument number
> in order to match it to the arguments in the actual call. The natural
> way to do that is to count the argument names in the synopsis (at
> least those not preceded by an unterminated bracket or comment) and
> stop when that name is found. For example if that is the first
> argument name after the "(" in the synopsis then it would be natural
> to conclude that it matches the first argument to the call, and not
> continue scanning to see if there is another occurrence of the same
> argument name.
>
> So I agree with Michael that this change is a good one to make the man
> pages less confusing. Thanks for creating the change.
>
> - Mark
^ permalink raw reply [flat|nested] 27+ messages in thread