Hi Chris, Joseph, On Tue, Sep 09, 2025 at 08:56:28PM +0200, Alejandro Colomar wrote: > Hi Joseph, > > On Tue, Sep 09, 2025 at 12:04:47PM +0000, Joseph Myers wrote: > > On Tue, 9 Sep 2025, Alejandro Colomar wrote: > > > > > > I don't think we should support any of these. We tightened up various > > > > cases of void in parameter lists in C2y (constraint "A parameter > > > > declaration shall not specify a void type, except for the special case > > > > of > > > > a single unnamed parameter of type void with no storage-class > > > > specifier, > > > > no type qualifier, and no following ellipsis terminator.", > > > > > > > > > > > > > replacing > > > > previous implicit UB), > > > > > > Could you please mention the paper number that did this? It would be > > > useful to read it. > > > > This was N3344 (alternative 1 accepted in Minneapolis). > > I don't think any of what I proposed conflicts in any way N3344. > > In f(void; void) there's only one unnamed parameter of type void, both > in the list of forward declarations and in the list of actual > declarations.
I've started implementing this, and found the current special-case of
void to be a bit weird. Here's the patch that I wrote, to remove the
parsing error when finding a leading ';', which already is a decent
improvement. I don't see any reason why that should be a parsing error.
(I still haven't checked if there are any regressions; I'll check in the
following days).
diff --git i/gcc/c/c-parser.cc w/gcc/c/c-parser.cc
index f1aaab12e6e..a14d364ed08 100644
--- i/gcc/c/c-parser.cc
+++ w/gcc/c/c-parser.cc
@@ -5349,11 +5349,6 @@ c_parser_parameter_declaration (c_parser
*parser, tree attrs,
error_at (token->location, "unknown type name %qE",
token->value);
parser->error = true;
}
- /* ??? In some Objective-C cases '...' isn't applicable so there
- should be a different message. */
- else
- c_parser_error (parser,
- "expected declaration specifiers or %<...%>");
c_parser_skip_to_end_of_parameter (parser);
return NULL;
}
That allows me to write something like
void f(; int n);
void g(;);
However, the special-case handling of 'void' makes evident that
something isn't well abstracted within GCC. It checks that there's one
void, but it should be one void per list of declarations, not one void
in total.
alx@debian:~/tmp$ cat fwd.c
// Must remain as errors:
void f(void n); // error: ‘void’ must be the only parameter and
unnamed
void g(void, int n); // error: ‘void’ must be the only parameter and
unnamed
void h(int n, void); // error: ‘void’ must be the only parameter and
unnamed
void i(int n; void); // error: parameter ‘n’ has just a forward
declaration
// Should be valid:
void j(;); // ok
void k(;void); // ok
// Whatever, but at least should be self-consistent:
void l(void;); // ok
void m(void; void); // error: ‘void’ must be the only parameter and
unnamed
void n(void; int n); // error: parameter ‘({anonymous})’ has just a
forward declaration
Regardless of whether we want l(), m(), and n() to be accepted, they
should either be all accepted or none accepted. I think all should be
accepted, but you might convince me otherwise.
The code checking for the single 'void' is before the loop that parses
all declarations. I think that check should be put into the loop, and
should be distinct for each of the two (or more) lists.
What do you think?
Have a lovely day!
Alex
--
<https://www.alejandro-colomar.es>
Use port 80 (that is, <...:80/>).
signature.asc
Description: PGP signature
