* Mangled function prototypes (phantom arguments)
@ 2026-05-27 12:14 Michael Kerrisk (man7.org)
2026-05-27 13:47 ` Alejandro Colomar
0 siblings, 1 reply; 13+ messages in thread
From: Michael Kerrisk (man7.org) @ 2026-05-27 12:14 UTC (permalink / raw)
To: Alejandro Colomar; +Cc: linux-man
Hello Alex,
It looks like some scripted changes have mangled the call signatures
in multiple SYSNOPIS sections in section 2. (In some cases, multiple
call signatures in the same SYNOPSIS have the problem.)
The problems have all resulted in prototypes adding a phantom first
argument. See for example this prototype from read.2:
ssize_t read(size_t count;
int fd, void buf[count], size_t count);
As far as I can see, at least the following pages are affected:
add_key
alloc_hugepages
cacheflush
epoll_wait
futex_waitv
getdents
getdents64
getdomainname
get_mempolicy
getrandom
getsockopt
getunwind
getxattr
init_module
listmount
lookup_dcookie
madvise
mbind
mincore
mlock
mmap
modify_ldt
mprotect
mremap
msgop
msync
perfmonctl
pread
process_madvise
query_module
read
readlink
recv
recvmsg
remap_file_pages
s390_pci_mmio_write
send
sendmsg
setxattr
write
I did a quick scripted check of section 3 pages, but spotted no problems there.
Thanks,
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] 13+ messages in thread
* Re: Mangled function prototypes (phantom arguments)
2026-05-27 12:14 Mangled function prototypes (phantom arguments) Michael Kerrisk (man7.org)
@ 2026-05-27 13:47 ` Alejandro Colomar
2026-05-27 16:46 ` Michael Kerrisk (man7.org)
0 siblings, 1 reply; 13+ messages in thread
From: Alejandro Colomar @ 2026-05-27 13:47 UTC (permalink / raw)
To: Michael Kerrisk (man7.org); +Cc: linux-man
[-- Attachment #1: Type: text/plain, Size: 4051 bytes --]
Hi Michael,
On 2026-05-27T14:14:39+0200, Michael Kerrisk (man7.org) wrote:
> Hello Alex,
>
> It looks like some scripted changes have mangled the call signatures
> in multiple SYSNOPIS sections in section 2. (In some cases, multiple
> call signatures in the same SYNOPSIS have the problem.)
It wasn't scripted changes; they were hand-written. Here are the
relevant commits:
d2c2db8830f8 (2025-03-14; "man/: SYNOPSIS: Use GNU forward-declarations of parameters for sizes of array parameters")
24b307093047 (2025-03-20; "man/man2/get_mempolicy.2: SYNOPSIS: Use GNU fwd declaration of parameters for sizes of array parameters")
8eea66b827a1 (2025-06-28; "man/: SYNOPSIS: Don't highlight forward declarations of function parameters")
3d066f79ac04 (2025-08-20; "man/man2/: SYNOPSIS: Use GNU forward-declarations of parameters for sizes of array parameters")
f376c5ad0fa9 (2025-10-29; "bin/grepc: -tfp, -tfd: Add support for forward-declarations of parameters")
> The problems have all resulted in prototypes adding a phantom first
> argument. See for example this prototype from read.2:
>
> ssize_t read(size_t count;
> int fd, void buf[count], size_t count);
This is valid C (except for the array of void, but that's a separate
topic).
Here's for example the prototype shown in the SYNOPSIS of confstr(3):
size_t confstr(size_t size;
int name, char buf[size], size_t size);
I've chosen this one because it doesn't use void. If you try compiling
it, it will work:
alx@devuan:~/tmp$ cat test.c
typedef long size_t;
size_t
confstr(size_t size;
int name, char buf[size], size_t size);
alx@devuan:~/tmp$ gcc -Wall -Wextra -S test.c
alx@devuan:~/tmp$
And it does the right thing. The function has 3 parameters.
It's documented in GCC's documentation here:
<https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html>
It's a forward declaration of function parameters. It allows using
parameters that come later, to be used in array length expressions. See
at the bottom of the link above. I'll paste the GCC documentation here
for completeness, anyway:
If you want to pass the array first and the length afterward,
you can use a forward declaration in the parameter list—another
GNU extension.
struct entry
tester (int len; char data[len][len], int len)
{
/* … */
}
The ‘int len’ before the semicolon is a parameter forward
declaration, and it serves the purpose of making the name len
known when the declaration of data is parsed.
Lists of parameter forward declarations are terminated by
semicolons, and parameter forward declarations are separated
within such lists by commas, just like in the regular list of
parameter declarations.
You can write any number of lists of parameter forward
declaration, but using more than one is unnecessary. The last
semicolon is followed by the list of parameter declarations.
Each parameter forward declaration must match a parameter
declaration in parameter name and data type. ISO C99 does not
support parameter forward declarations.
> As far as I can see, at least the following pages are affected:
All functions that have an array parameter whose length is specified by
a parameter that goes after the array parameter are affected (unless I
missed some accidentally). This is intentional.
>
> add_key
[...]
> write
>
> I did a quick scripted check of section 3 pages, but spotted no problems there.
There are quite some, actually. In fact, more than in man2.
$ find man2/ -type f \
| xargs mansectf SYNOPSIS \
| grep '^[^(]*([^)]*;' \
| sed 's/(.*//' \
| sed 's/.* //' \
| tr -d '*' \
| wc -l;
65
$ find man3/ -type f \
| xargs mansectf SYNOPSIS \
| grep '^[^(]*([^)]*;' \
| sed 's/(.*//' \
| sed 's/.* //' \
| tr -d '*' \
| wc -l;
156
>
> Thanks,
>
> Michael
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] 13+ messages in thread
* Re: Mangled function prototypes (phantom arguments)
2026-05-27 13:47 ` Alejandro Colomar
@ 2026-05-27 16:46 ` Michael Kerrisk (man7.org)
2026-05-27 17:58 ` Alejandro Colomar
0 siblings, 1 reply; 13+ messages in thread
From: Michael Kerrisk (man7.org) @ 2026-05-27 16:46 UTC (permalink / raw)
To: Alejandro Colomar; +Cc: linux-man
Hello Alex,
Thanks for responding.
> > The problems have all resulted in prototypes adding a phantom first
> > argument. See for example this prototype from read.2:
> >
> > ssize_t read(size_t count;
> > int fd, void buf[count], size_t count);
>
> This is valid C (except for the array of void, but that's a separate
> topic).
As we see, I'm not keeping up with my C :-).
Is this a GNU extension? Or part of the standard? Or an upcoming part
of the standard?
Thanks,
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] 13+ messages in thread
* Re: Mangled function prototypes (phantom arguments)
2026-05-27 16:46 ` Michael Kerrisk (man7.org)
@ 2026-05-27 17:58 ` Alejandro Colomar
2026-05-28 13:06 ` Michael Kerrisk (man7.org)
0 siblings, 1 reply; 13+ messages in thread
From: Alejandro Colomar @ 2026-05-27 17:58 UTC (permalink / raw)
To: Michael Kerrisk (man7.org); +Cc: linux-man
[-- Attachment #1: Type: text/plain, Size: 1160 bytes --]
Hi Michael,
On 2026-05-27T18:46:06+0200, Michael Kerrisk (man7.org) wrote:
> Hello Alex,
>
> Thanks for responding.
>
> > > The problems have all resulted in prototypes adding a phantom first
> > > argument. See for example this prototype from read.2:
> > >
> > > ssize_t read(size_t count;
> > > int fd, void buf[count], size_t count);
> >
> > This is valid C (except for the array of void, but that's a separate
> > topic).
>
> As we see, I'm not keeping up with my C :-).
To be fair, this is a very little-known feature (even though it's a very
old one). I (and a few others) are trying to make it more well known,
as it's quite interesting.
>
> Is this a GNU extension? Or part of the standard? Or an upcoming part
> of the standard?
It is a very old GNU extension. For decades, almost nobody had been
interested in it (I've never seen it used in the wild). One or two
years ago, we started discussing it in the C Committee; several of us
want it to be standard. However, Clang is vetoing it.
Cheers,
Alex
>
> Thanks,
>
> Michael
--
<https://www.alejandro-colomar.es>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Mangled function prototypes (phantom arguments)
2026-05-27 17:58 ` Alejandro Colomar
@ 2026-05-28 13:06 ` Michael Kerrisk (man7.org)
2026-05-28 14:25 ` Alejandro Colomar
2026-05-28 18:39 ` Carlos O'Donell
0 siblings, 2 replies; 13+ messages in thread
From: Michael Kerrisk (man7.org) @ 2026-05-28 13:06 UTC (permalink / raw)
To: Alejandro Colomar; +Cc: linux-man
Hi Alex,
On Wed, 27 May 2026 at 19:58, Alejandro Colomar <alx@kernel.org> wrote:
>
> Hi Michael,
>
> On 2026-05-27T18:46:06+0200, Michael Kerrisk (man7.org) wrote:
> > Hello Alex,
> >
> > Thanks for responding.
> >
> > > > The problems have all resulted in prototypes adding a phantom first
> > > > argument. See for example this prototype from read.2:
> > > >
> > > > ssize_t read(size_t count;
> > > > int fd, void buf[count], size_t count);
> > >
> > > This is valid C (except for the array of void, but that's a separate
> > > topic).
> >
> > As we see, I'm not keeping up with my C :-).
>
> To be fair, this is a very little-known feature (even though it's a very
> old one). I (and a few others) are trying to make it more well known,
> as it's quite interesting.
I don't think the Linux system call and C library manual pages are a
good place to promote this obscure GNU feature. It is confusing
people, including me. (I came to making this report because several
people have reported this "bug" on various pages rendered at
man7.org.)
Please consider reverting these changes. These markings use
little-understood, nonportable syntax. The manual page synopses should
be in standard, portable C that is *easy* to understand.
Thanks,
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] 13+ messages in thread
* Re: Mangled function prototypes (phantom arguments)
2026-05-28 13:06 ` Michael Kerrisk (man7.org)
@ 2026-05-28 14:25 ` Alejandro Colomar
2026-05-28 18:39 ` Carlos O'Donell
1 sibling, 0 replies; 13+ messages in thread
From: Alejandro Colomar @ 2026-05-28 14:25 UTC (permalink / raw)
To: Michael Kerrisk (man7.org); +Cc: linux-man
[-- Attachment #1: Type: text/plain, Size: 4876 bytes --]
Hi Michael,
On 2026-05-28T15:06:10+0200, Michael Kerrisk (man7.org) wrote:
> > > > > The problems have all resulted in prototypes adding a phantom first
> > > > > argument. See for example this prototype from read.2:
> > > > >
> > > > > ssize_t read(size_t count;
> > > > > int fd, void buf[count], size_t count);
> > > >
> > > > This is valid C (except for the array of void, but that's a separate
> > > > topic).
> > >
> > > As we see, I'm not keeping up with my C :-).
> >
> > To be fair, this is a very little-known feature (even though it's a very
> > old one). I (and a few others) are trying to make it more well known,
> > as it's quite interesting.
>
> I don't think the Linux system call and C library manual pages are a
> good place to promote this obscure GNU feature. It is confusing
> people, including me. (I came to making this report because several
> people have reported this "bug" on various pages rendered at
> man7.org.)
I understand the initial confusion, but I believe once an initial period
is overcome, the extra information will be very helpful to the reader.
> Please consider reverting these changes.
I've been thinking about this topic for some time already, and I will
keep these changes.
> These markings use
> little-understood, nonportable syntax.
While they're little understood, and certainly not portable, they're
also easy to learn.
On the other hand, manual pages have --for a long time-- lacked a lot
of information about parameters that could be expressed in the synopses
easily. This includes nullability of arguments, lenghts of arrays, and
overlapping of pointers. Those are now documented with Clang's
_Nullable, GNU forward declarations of function parameters, and
'restrict'. Of those, only 'restrict' is portable.
Having to document that information in the description would be (was)
counter-productive, as the information is difficult to find,
inconsistent across pages, and adds to the wall of text. Having that
information in a consistent and concise way specified in the synopsis
allows reducing the wall of text, and is significantly less ambiguous.
This change has significantly improved my own reading of manual pages,
where I can now reasonably understand most APIs by just looking at the
synopsis. I've also --like you-- received many reports of people
surprised by this syntax, but most of them seem to be okay with it once
I explain it to them and point them to GCC's documentation of the
feature. And then there are several other users that have reported very
positive feedback regarding the array and nullability annotations in the
synopses, claiming that they're now much more informative, and thanking
me for the change.
I think it's overall a positive change.
> The manual page synopses should
> be in standard, portable C that is *easy* to understand.
This has never been fully true; we've always had exceptions to the rule.
We have counter-examples:
- The old version of open(2) had two prototypes, which is not valid C
(it's valid C++, though):
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
We agreed to change it to the real prototype some years ago:
int open(const char *path, int flags, ...
/* mode_t mode */ );
BTW, I'll soon have to start using this C++ notation for string
functions, since ISO C23 has changed the API of things like
strchr(3), to preserve the const qualifier in the return value. This
has been implemented in glibc 2.43. Now, strchr(3) is specified (and
implemented) as if:
char *strchr(char *s, int c);
const char *strchr(const char *s, int c);
The actual ISO C specification uses 'QChar' to make it more compact:
QChar *strchr(QChar *s, int c);
However, 'QChar' is less known by the general public, so C++ syntax
seems better for manual pages. That is, we'll recover this
exception that was once used in open(2).
This is a breaking change that some users have noticed and reported.
- We have pages where we mix constants with the prototype. There are
old examples of this, although the most common is the system calls
that don't have a wrapper.
int syscall(SYS_membarrier, int cmd, unsigned int flags, int cpu_id);
- The assert(3) macro was specified as taking a scalar (which is not
a type):
void assert(scalar expression);
I've changed it to take a C99 'bool', which has the same effect.
void assert(bool expression);
About being easy to understand, I believe you'll understand it forever
since now, since it's not inherently complex. I hope the same is true
of other readers.
>
> Thanks,
>
> Michael
Cheers,
Alex
--
<https://www.alejandro-colomar.es>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Mangled function prototypes (phantom arguments)
2026-05-28 13:06 ` Michael Kerrisk (man7.org)
2026-05-28 14:25 ` Alejandro Colomar
@ 2026-05-28 18:39 ` Carlos O'Donell
2026-05-28 21:24 ` Alejandro Colomar
1 sibling, 1 reply; 13+ messages in thread
From: Carlos O'Donell @ 2026-05-28 18:39 UTC (permalink / raw)
To: Michael Kerrisk (man7.org), Alejandro Colomar; +Cc: linux-man
On 5/28/26 9:06 AM, Michael Kerrisk (man7.org) wrote:
> I don't think the Linux system call and C library manual pages are a
> good place to promote this obscure GNU feature. It is confusing
> people, including me. (I came to making this report because several
> people have reported this "bug" on various pages rendered at
> man7.org.)
>
> Please consider reverting these changes. These markings use
> little-understood, nonportable syntax. The manual page synopses should
> be in standard, portable C that is *easy* to understand.
I agree with Michael.
I think these changes should be reverted, but it's a question of
goals and values for the project, and the purpose of the SYNOPSIS.
My view was always that they were the simplest expression of the
interface that the widest possible audience could understand, and
that seems to align with Michael's view.
It certainly isn't for me as a C library author... it's for
someone just learning or refreshing knowledge, and what makes
it easiest for a new person or someone less familiar to consume?
It seems like we've drifted toward describing the interface *and*
the constraints in a compact form (like N3433). Is that in line
with the goals of the project?
It's not like these are the *real* prototypes in your C library,
since those are much much more complicated and difficult to
understand. It's also not like they match the GNU C Library
manual's description via `info libc mmap` that are presented
to users of the library.
What is the intent of the SYNOPSIS field and the prototypes
therein? What are the goals or values of the project around
that information?
There is certainly some syntax that is valuable for compilers
enforcing constraints and providing warnings, but is that
valuable for man pages readers?
For manual pages overall I think the forward declarations
are a net negative change in readability. I would continue
to express the constraints in plain prose.
$0.02.
--
Cheers,
Carlos.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Mangled function prototypes (phantom arguments)
2026-05-28 18:39 ` Carlos O'Donell
@ 2026-05-28 21:24 ` Alejandro Colomar
2026-05-28 21:43 ` Mark Harris
2026-05-28 22:56 ` Alejandro Colomar
0 siblings, 2 replies; 13+ messages in thread
From: Alejandro Colomar @ 2026-05-28 21:24 UTC (permalink / raw)
To: Carlos O'Donell; +Cc: Michael Kerrisk (man7.org), linux-man
[-- Attachment #1: Type: text/plain, Size: 5981 bytes --]
Hi Carlos,
On 2026-05-28T14:39:15-0400, Carlos O'Donell wrote:
> On 5/28/26 9:06 AM, Michael Kerrisk (man7.org) wrote:
> > I don't think the Linux system call and C library manual pages are a
> > good place to promote this obscure GNU feature. It is confusing
> > people, including me. (I came to making this report because several
> > people have reported this "bug" on various pages rendered at
> > man7.org.)
> >
> > Please consider reverting these changes. These markings use
> > little-understood, nonportable syntax. The manual page synopses should
> > be in standard, portable C that is *easy* to understand.
>
> I agree with Michael.
>
> I think these changes should be reverted, but it's a question of
> goals and values for the project, and the purpose of the SYNOPSIS.
>
> My view was always that they were the simplest expression of the
> interface that the widest possible audience could understand, and
> that seems to align with Michael's view.
That doesn't provide much value, IMHO. My opinion of the SYNOPSIS is
that it's a quick reminder of how a function should be used.
Let's take a real example:
long mbind(void *addr, unsigned long len, int mode,
const unsigned long *nodemask, unsigned long maxnode,
unsigned int flags);
I honestly don't know anything from the prototype above. Apart from the
types, there's no useful information. There are the names which will
later be described in the description, but so far they're not useful.
long mbind(unsigned long size, unsigned long maxnode;
void addr[size], unsigned long size, int mode,
const unsigned long nodemask[(maxnode + ULONG_WIDTH - 1)
/ ULONG_WIDTH],
unsigned long maxnode, unsigned int flags);
This already introduces me the function quite well. The description
will of course clarify details, but I can already see some things.
> It certainly isn't for me as a C library author...
The SYNOPSIS is for everyone. I read the synopses regularly while
programming. In fact, I read it quite more than the descriptions, which
I only read seldom, when interested in some rare details.
> it's for
> someone just learning or refreshing knowledge, and what makes
> it easiest for a new person or someone less familiar to consume?
Speaking of myself as a new programmer not so long ago, I would have
appreciated these synopses.
> It seems like we've drifted toward describing the interface *and*
> the constraints in a compact form (like N3433). Is that in line
> with the goals of the project?
I think it is. At least with how I see it.
I also don't see much difference between the interface and its
constraints. They are deeply related (array parameters are part of the
type system, after all). If we wanted to know the names of the
arguments and their order, we could have something much simpler:
mbind(addr, size, mode, nodemask, maxnode, flags);
But of course we don't want that.
> It's not like these are the *real* prototypes in your C library,
Implementation details are unimportant.
> since those are much much more complicated and difficult to
> understand. It's also not like they match the GNU C Library
> manual's description via `info libc mmap` that are presented
> to users of the library.
I don't see why both documentations should agree in the details. Of
course, I'd like the libc manual to be more detailed, but there's no
inherent reason why both should be exact matches, as long as they're
compatible.
> What is the intent of the SYNOPSIS field and the prototypes
> therein? What are the goals or values of the project around
> that information?
That information should introduce the API, giving enough details to
understand a decent amount of it. It should also remind quickly of
some details such as whether an argument may be null, or which sizes
correspond to which arrays, so that programmers can quickly check those.
> There is certainly some syntax that is valuable for compilers
> enforcing constraints and providing warnings, but is that
> valuable for man pages readers?
For me, as a frequent reader, it is very valuable. YMMV.
> For manual pages overall I think the forward declarations
> are a net negative change in readability. I would continue
> to express the constraints in plain prose.
I tend to disagree. For example, let's consider the addition of
'restrict' (I added it a few years ago, when Michael was still around,
IIRC).
$ find man -type f | xargs grep -rl '[[*]restrict' | wc -l;
137
Here's the prose in memcpy(3), which I haven't removed yet (because it's
historically more relevant in memcpy(3)):
CAVEATS
Failure to observe the requirement that the memory areas do not overlap
has been the source of significant bugs. (POSIX and the C standards are
explicit that employing memcpy() with overlapping areas produces undefined
behavior.) Most notably, in glibc 2.13 a performance optimization of mem‐
cpy() on some platforms (including x86‐64) included changing the order in
which bytes were copied from src to dest.
If we had to replicate this paragraph in 137 pages, we'd be adding walls
of text unnecessarily. And it would be a problem for maintaining that
text. Now that we use 'restrict', it's just a few keywords in the
SYNOPSIS, and it's all well documented (but you need to know what that
keyword means, of course; there's a trade-off). (Another matter is that
'restrict' is utterly broken as a keyword for source code; but for
documentation purposes it's relatively fine. The same thing happens
with Clang's _Nullable, which has never really worked in source code.)
Have a lovely night!
Alex
>
> $0.02.
>
> --
> Cheers,
> Carlos.
>
--
<https://www.alejandro-colomar.es>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Mangled function prototypes (phantom arguments)
2026-05-28 21:24 ` Alejandro Colomar
@ 2026-05-28 21:43 ` Mark Harris
2026-05-28 22:10 ` Alejandro Colomar
2026-05-28 22:56 ` Alejandro Colomar
1 sibling, 1 reply; 13+ messages in thread
From: Mark Harris @ 2026-05-28 21:43 UTC (permalink / raw)
To: Alejandro Colomar
Cc: Carlos O'Donell, Michael Kerrisk (man7.org), linux-man
Alejandro Colomar wrote:
>
> Hi Carlos,
>
> On 2026-05-28T14:39:15-0400, Carlos O'Donell wrote:
> > On 5/28/26 9:06 AM, Michael Kerrisk (man7.org) wrote:
> > > I don't think the Linux system call and C library manual pages are a
> > > good place to promote this obscure GNU feature. It is confusing
> > > people, including me. (I came to making this report because several
> > > people have reported this "bug" on various pages rendered at
> > > man7.org.)
> > >
> > > Please consider reverting these changes. These markings use
> > > little-understood, nonportable syntax. The manual page synopses should
> > > be in standard, portable C that is *easy* to understand.
> >
> > I agree with Michael.
> >
> > I think these changes should be reverted, but it's a question of
> > goals and values for the project, and the purpose of the SYNOPSIS.
> >
> > My view was always that they were the simplest expression of the
> > interface that the widest possible audience could understand, and
> > that seems to align with Michael's view.
>
> That doesn't provide much value, IMHO. My opinion of the SYNOPSIS is
> that it's a quick reminder of how a function should be used.
I suggest a compromise. Keep the array sizes, which are the part that
you claim adds value, and drop the forward declarations, which are the
part that confuses people. So for example:
ssize_t read(int fd, void buf[count], size_t count);
Yes, count is used before its definition, but the goal is not to write
a valid function declaration; the existing one being invalid is
evidence of that. It is difficult to imagine that anyone would have
trouble finding the definition of count without a forward declaration,
unless they are a compiler in which case they would also be tripped up
by the array-of-void.
- Mark
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Mangled function prototypes (phantom arguments)
2026-05-28 21:43 ` Mark Harris
@ 2026-05-28 22:10 ` Alejandro Colomar
2026-05-28 22:11 ` Alejandro Colomar
0 siblings, 1 reply; 13+ messages in thread
From: Alejandro Colomar @ 2026-05-28 22:10 UTC (permalink / raw)
To: Mark Harris; +Cc: Carlos O'Donell, Michael Kerrisk (man7.org), linux-man
[-- Attachment #1: Type: text/plain, Size: 1813 bytes --]
Hi Mark,
On 2026-05-28T14:43:21-0700, Mark Harris wrote:
> > > My view was always that they were the simplest expression of the
> > > interface that the widest possible audience could understand, and
> > > that seems to align with Michael's view.
> >
> > That doesn't provide much value, IMHO. My opinion of the SYNOPSIS is
> > that it's a quick reminder of how a function should be used.
>
> I suggest a compromise. Keep the array sizes, which are the part that
> you claim adds value, and drop the forward declarations, which are the
> part that confuses people. So for example:
>
> ssize_t read(int fd, void buf[count], size_t count);
>
> Yes, count is used before its definition, but the goal is not to write
> a valid function declaration; the existing one being invalid is
> evidence of that. It is difficult to imagine that anyone would have
> trouble finding the definition of count without a forward declaration,
> unless they are a compiler in which case they would also be tripped up
> by the array-of-void.
I considered doing that some time ago. I am worried about something: it
might "work" if you're unlucky.
Let's say a relatively new programmer sees this and thinks it's valid C.
And let's say it tries it in their own code, which may have a variable
in scope (most likely, a global one) named 'count'.
extern int count;
ssize_t read(int fd, void buf[count], size_t count);
That's going to compile, but it's not what you'd expect.
That's why I originally used [.count] notation. That one if free from
this problem. However, GCC maintainers convinced me of using some
syntax that is valid C (at least in the GNU dialect of it, which is the
majoritary one anyway).
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] 13+ messages in thread
* Re: Mangled function prototypes (phantom arguments)
2026-05-28 22:10 ` Alejandro Colomar
@ 2026-05-28 22:11 ` Alejandro Colomar
0 siblings, 0 replies; 13+ messages in thread
From: Alejandro Colomar @ 2026-05-28 22:11 UTC (permalink / raw)
To: Mark Harris; +Cc: Carlos O'Donell, Michael Kerrisk (man7.org), linux-man
[-- Attachment #1: Type: text/plain, Size: 2126 bytes --]
On 2026-05-29T00:10:23+0200, Alejandro Colomar wrote:
> Hi Mark,
>
> On 2026-05-28T14:43:21-0700, Mark Harris wrote:
> > > > My view was always that they were the simplest expression of the
> > > > interface that the widest possible audience could understand, and
> > > > that seems to align with Michael's view.
> > >
> > > That doesn't provide much value, IMHO. My opinion of the SYNOPSIS is
> > > that it's a quick reminder of how a function should be used.
> >
> > I suggest a compromise. Keep the array sizes, which are the part that
> > you claim adds value, and drop the forward declarations, which are the
> > part that confuses people. So for example:
> >
> > ssize_t read(int fd, void buf[count], size_t count);
> >
> > Yes, count is used before its definition, but the goal is not to write
> > a valid function declaration; the existing one being invalid is
> > evidence of that. It is difficult to imagine that anyone would have
> > trouble finding the definition of count without a forward declaration,
> > unless they are a compiler in which case they would also be tripped up
> > by the array-of-void.
>
> I considered doing that some time ago. I am worried about something: it
> might "work" if you're unlucky.
>
> Let's say a relatively new programmer sees this and thinks it's valid C.
> And let's say it tries it in their own code, which may have a variable
> in scope (most likely, a global one) named 'count'.
>
> extern int count;
>
> ssize_t read(int fd, void buf[count], size_t count);
>
> That's going to compile, but it's not what you'd expect.
Oh well, this one won't compile, because of void. But it would work for
other arrays, such as arrays of char.
>
> That's why I originally used [.count] notation. That one if free from
> this problem. However, GCC maintainers convinced me of using some
> syntax that is valid C (at least in the GNU dialect of it, which is the
> majoritary one anyway).
>
>
> Have a lovely night!
> Alex
>
> --
> <https://www.alejandro-colomar.es>
--
<https://www.alejandro-colomar.es>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Mangled function prototypes (phantom arguments)
2026-05-28 21:24 ` Alejandro Colomar
2026-05-28 21:43 ` Mark Harris
@ 2026-05-28 22:56 ` Alejandro Colomar
2026-05-28 23:22 ` Mark Harris
1 sibling, 1 reply; 13+ messages in thread
From: Alejandro Colomar @ 2026-05-28 22:56 UTC (permalink / raw)
To: Carlos O'Donell; +Cc: Michael Kerrisk (man7.org), linux-man
[-- Attachment #1: Type: text/plain, Size: 7136 bytes --]
On 2026-05-28T23:24:06+0200, Alejandro Colomar wrote:
> Hi Carlos,
>
> On 2026-05-28T14:39:15-0400, Carlos O'Donell wrote:
> > On 5/28/26 9:06 AM, Michael Kerrisk (man7.org) wrote:
> > > I don't think the Linux system call and C library manual pages are a
> > > good place to promote this obscure GNU feature. It is confusing
> > > people, including me. (I came to making this report because several
> > > people have reported this "bug" on various pages rendered at
> > > man7.org.)
> > >
> > > Please consider reverting these changes. These markings use
> > > little-understood, nonportable syntax. The manual page synopses should
> > > be in standard, portable C that is *easy* to understand.
> >
> > I agree with Michael.
> >
> > I think these changes should be reverted, but it's a question of
> > goals and values for the project, and the purpose of the SYNOPSIS.
> >
> > My view was always that they were the simplest expression of the
> > interface that the widest possible audience could understand, and
> > that seems to align with Michael's view.
>
> That doesn't provide much value, IMHO. My opinion of the SYNOPSIS is
> that it's a quick reminder of how a function should be used.
>
> Let's take a real example:
>
> long mbind(void *addr, unsigned long len, int mode,
> const unsigned long *nodemask, unsigned long maxnode,
> unsigned int flags);
>
> I honestly don't know anything from the prototype above. Apart from the
> types, there's no useful information. There are the names which will
> later be described in the description, but so far they're not useful.
>
> long mbind(unsigned long size, unsigned long maxnode;
> void addr[size], unsigned long size, int mode,
> const unsigned long nodemask[(maxnode + ULONG_WIDTH - 1)
> / ULONG_WIDTH],
> unsigned long maxnode, unsigned int flags);
>
> This already introduces me the function quite well. The description
> will of course clarify details, but I can already see some things.
>
> > It certainly isn't for me as a C library author...
>
> The SYNOPSIS is for everyone. I read the synopses regularly while
> programming. In fact, I read it quite more than the descriptions, which
> I only read seldom, when interested in some rare details.
>
> > it's for
> > someone just learning or refreshing knowledge, and what makes
> > it easiest for a new person or someone less familiar to consume?
>
> Speaking of myself as a new programmer not so long ago, I would have
> appreciated these synopses.
>
> > It seems like we've drifted toward describing the interface *and*
> > the constraints in a compact form (like N3433). Is that in line
> > with the goals of the project?
>
> I think it is. At least with how I see it.
>
> I also don't see much difference between the interface and its
> constraints. They are deeply related (array parameters are part of the
> type system, after all). If we wanted to know the names of the
> arguments and their order, we could have something much simpler:
>
> mbind(addr, size, mode, nodemask, maxnode, flags);
BTW, FWIW, this resembles quite a lot the documentation from the times
of V7 Unix. Here's how functions were documented back then.
SYNOPSIS
char *ttyname(fildes)
isatty(fildes)
ttyslot()
AFAICS, 4.4BSD is the first BSD that used function prototypes (both in
the source code and documentation). You could similarly argue that that
was unnecessarily confusing programmers back then (most programmers of
the time might not be aware of the innovation of function prototypes,
and why one would care about parameter types, especially when being
introduced to a function). However, we'll probably agree that that was
a good change. I would find a prototype without types to be quite
uninformative.
Cheers,
Alex
>
> But of course we don't want that.
>
> > It's not like these are the *real* prototypes in your C library,
>
> Implementation details are unimportant.
>
> > since those are much much more complicated and difficult to
> > understand. It's also not like they match the GNU C Library
> > manual's description via `info libc mmap` that are presented
> > to users of the library.
>
> I don't see why both documentations should agree in the details. Of
> course, I'd like the libc manual to be more detailed, but there's no
> inherent reason why both should be exact matches, as long as they're
> compatible.
>
> > What is the intent of the SYNOPSIS field and the prototypes
> > therein? What are the goals or values of the project around
> > that information?
>
> That information should introduce the API, giving enough details to
> understand a decent amount of it. It should also remind quickly of
> some details such as whether an argument may be null, or which sizes
> correspond to which arrays, so that programmers can quickly check those.
>
> > There is certainly some syntax that is valuable for compilers
> > enforcing constraints and providing warnings, but is that
> > valuable for man pages readers?
>
> For me, as a frequent reader, it is very valuable. YMMV.
>
> > For manual pages overall I think the forward declarations
> > are a net negative change in readability. I would continue
> > to express the constraints in plain prose.
>
> I tend to disagree. For example, let's consider the addition of
> 'restrict' (I added it a few years ago, when Michael was still around,
> IIRC).
>
> $ find man -type f | xargs grep -rl '[[*]restrict' | wc -l;
> 137
>
> Here's the prose in memcpy(3), which I haven't removed yet (because it's
> historically more relevant in memcpy(3)):
>
> CAVEATS
> Failure to observe the requirement that the memory areas do not overlap
> has been the source of significant bugs. (POSIX and the C standards are
> explicit that employing memcpy() with overlapping areas produces undefined
> behavior.) Most notably, in glibc 2.13 a performance optimization of mem‐
> cpy() on some platforms (including x86‐64) included changing the order in
> which bytes were copied from src to dest.
>
> If we had to replicate this paragraph in 137 pages, we'd be adding walls
> of text unnecessarily. And it would be a problem for maintaining that
> text. Now that we use 'restrict', it's just a few keywords in the
> SYNOPSIS, and it's all well documented (but you need to know what that
> keyword means, of course; there's a trade-off). (Another matter is that
> 'restrict' is utterly broken as a keyword for source code; but for
> documentation purposes it's relatively fine. The same thing happens
> with Clang's _Nullable, which has never really worked in source code.)
>
>
> Have a lovely night!
> Alex
>
> >
> > $0.02.
> >
> > --
> > Cheers,
> > Carlos.
> >
>
> --
> <https://www.alejandro-colomar.es>
--
<https://www.alejandro-colomar.es>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Mangled function prototypes (phantom arguments)
2026-05-28 22:56 ` Alejandro Colomar
@ 2026-05-28 23:22 ` Mark Harris
0 siblings, 0 replies; 13+ messages in thread
From: Mark Harris @ 2026-05-28 23:22 UTC (permalink / raw)
To: Alejandro Colomar
Cc: Carlos O'Donell, Michael Kerrisk (man7.org), linux-man
Alejandro Colomar wrote:
>
> On 2026-05-28T23:24:06+0200, Alejandro Colomar wrote:
> > Hi Carlos,
> >
> > On 2026-05-28T14:39:15-0400, Carlos O'Donell wrote:
> > > On 5/28/26 9:06 AM, Michael Kerrisk (man7.org) wrote:
> > > > I don't think the Linux system call and C library manual pages are a
> > > > good place to promote this obscure GNU feature. It is confusing
> > > > people, including me. (I came to making this report because several
> > > > people have reported this "bug" on various pages rendered at
> > > > man7.org.)
> > > >
> > > > Please consider reverting these changes. These markings use
> > > > little-understood, nonportable syntax. The manual page synopses should
> > > > be in standard, portable C that is *easy* to understand.
> > >
> > > I agree with Michael.
> > >
> > > I think these changes should be reverted, but it's a question of
> > > goals and values for the project, and the purpose of the SYNOPSIS.
> > >
> > > My view was always that they were the simplest expression of the
> > > interface that the widest possible audience could understand, and
> > > that seems to align with Michael's view.
> >
> > That doesn't provide much value, IMHO. My opinion of the SYNOPSIS is
> > that it's a quick reminder of how a function should be used.
> >
> > Let's take a real example:
> >
> > long mbind(void *addr, unsigned long len, int mode,
> > const unsigned long *nodemask, unsigned long maxnode,
> > unsigned int flags);
> >
> > I honestly don't know anything from the prototype above. Apart from the
> > types, there's no useful information. There are the names which will
> > later be described in the description, but so far they're not useful.
> >
> > long mbind(unsigned long size, unsigned long maxnode;
> > void addr[size], unsigned long size, int mode,
> > const unsigned long nodemask[(maxnode + ULONG_WIDTH - 1)
> > / ULONG_WIDTH],
> > unsigned long maxnode, unsigned int flags);
> >
> > This already introduces me the function quite well. The description
> > will of course clarify details, but I can already see some things.
> >
> > > It certainly isn't for me as a C library author...
> >
> > The SYNOPSIS is for everyone. I read the synopses regularly while
> > programming. In fact, I read it quite more than the descriptions, which
> > I only read seldom, when interested in some rare details.
> >
> > > it's for
> > > someone just learning or refreshing knowledge, and what makes
> > > it easiest for a new person or someone less familiar to consume?
> >
> > Speaking of myself as a new programmer not so long ago, I would have
> > appreciated these synopses.
> >
> > > It seems like we've drifted toward describing the interface *and*
> > > the constraints in a compact form (like N3433). Is that in line
> > > with the goals of the project?
> >
> > I think it is. At least with how I see it.
> >
> > I also don't see much difference between the interface and its
> > constraints. They are deeply related (array parameters are part of the
> > type system, after all). If we wanted to know the names of the
> > arguments and their order, we could have something much simpler:
> >
> > mbind(addr, size, mode, nodemask, maxnode, flags);
>
> BTW, FWIW, this resembles quite a lot the documentation from the times
> of V7 Unix. Here's how functions were documented back then.
>
> SYNOPSIS
> char *ttyname(fildes)
>
> isatty(fildes)
>
> ttyslot()
>
> AFAICS, 4.4BSD is the first BSD that used function prototypes (both in
> the source code and documentation). You could similarly argue that that
> was unnecessarily confusing programmers back then (most programmers of
> the time might not be aware of the innovation of function prototypes,
> and why one would care about parameter types, especially when being
> introduced to a function). However, we'll probably agree that that was
> a good change. I would find a prototype without types to be quite
> uninformative.
The types are documented. Originally the types of arguments and the
return type of a function defaulted to int, so there is no need to
write the type in that case. Argument and return types that were not
int were shown in the man pages, using the syntax that was used at the
time (arguments declared with their type after the close parenthesis
before the open brace).
The issue is not the inclusion of additional information, the issue is
the use of obscure non-standard syntax that introduces confusion. The
man page above uses the normal C syntax that C programmers at the time
were very familiar with.
- Mark
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2026-05-28 23:22 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-27 12:14 Mangled function prototypes (phantom arguments) Michael Kerrisk (man7.org)
2026-05-27 13:47 ` Alejandro Colomar
2026-05-27 16:46 ` Michael Kerrisk (man7.org)
2026-05-27 17:58 ` Alejandro Colomar
2026-05-28 13:06 ` Michael Kerrisk (man7.org)
2026-05-28 14:25 ` Alejandro Colomar
2026-05-28 18:39 ` Carlos O'Donell
2026-05-28 21:24 ` Alejandro Colomar
2026-05-28 21:43 ` Mark Harris
2026-05-28 22:10 ` Alejandro Colomar
2026-05-28 22:11 ` Alejandro Colomar
2026-05-28 22:56 ` Alejandro Colomar
2026-05-28 23:22 ` Mark Harris
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox