https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121563
--- Comment #15 from Harald van Dijk <harald at gigawatt dot nl> ---
(In reply to Christopher Bazley from comment #14)
> (In reply to Harald van Dijk from comment #12)
> > (In reply to Christopher Bazley from comment #11)
> > > It includes the following new argument against permitting
> > > duplicate forward declarations (which may or may not be persuasive to the
> > > reader).
> >
> > That isn't persuasive to me, no.
>
> It's not clear to me whether you read the relevant part of the paper,
I did.
> or
> only the words that I selectively quoted (which is my fault). The wider
> context is that "the redeclaration semantics of the C language already vary
> depending on the context in which a declaration appears". (In other words,
> an argument in favour of permitting duplicate forward declarations, because
> they appear in the context of a parameter-forward-declaration-list.)
My comment was pointing out that the redeclaration semantics *don't* vary like
you say, there is a very simple general rule that they all follow, that you are
proposing no longer following for parameter declarations. I also said that
could be justifiable, but I struggle with the not acknowledging that such a
rule even exists.
> > > Declarations that are valid at file scope are invalid in function scope:
> > >
> > > int x, x; // valid
> > > void f()
> > > {
> > > int x, x; // invalid
> > > }
> >
> > That is a bit misleading.
>
> It is potentially misleading that the two declarations above use the same
> derivation rule in the syntax but have different semantics. Nevertheless,
> both are declarations, as I wrote.
Yes. The ones at file scope are declarations that are not definitions. The ones
at block scope are declarations that are definitions. That's such an essential
difference in semantics that I'm going to mention that again here for the
avoidance of confusion.
> Parameter forward declarations do not use the same derivation rule as
> ordinary declarations, but they use the same derivation rule as parameter
> declarations (and are indistinguishable from them).
Sure, but as you also wrote just above, it's possible for constructs using the
same derivation rule in the syntax to have different semantics, so whether
parameter forward declarations and parameter declarations use the same syntax
is not sufficient to say whether their semantics should also be the same.
> "When existing syntax is given new semantics, it inevitably looks wrong
> (regardless of whether it is subjectively ugly or not) if those semantics
> contradict user expectations" (from my paper). If file-scope declarations
> didn't exist and someone invented them with the same syntax as
> function-scope declarations but different semantics then I think that would
> be confusing. I also think that "int x, x" looks wrong because
> function-scope declarations are more common than file-scope declarations.
So it sounds like you disagree with the existing general rule, not just for
parameter forward declarations but in general, and have based your opinion for
parameter forward declarations on that. My expectations as a user who gets and
likes that general rule are different.
> Of course, but you have modified the declarations in such a way that they no
> longer resemble one another.
Yes, because whether duplicate declarations are permitted depends on their
semantics, not their appearance, so I modified it so that their semantics are
sufficiently similar, rather than their appearance.
> If the syntax of parameter forward declarations
> required a storage-class specifier like 'extern' then there would be no
> ambiguity about whether they are definitions or not.
True. I think (and I think you will agree) that that would be a bad idea for
other reasons, but it would have avoided this particular problem.
> As you noted, "a typedef name can be redefined to denote the same type as it
> currently does, provided that type is not a variably modified type" (from
> the ISO standard). I don't think the fact this is called a definition rather
> than a declaration is relevant though.
Isn't it? Since the general rule I stated is that multiple declarations are
okay so long as there aren't multiple definitions, it seems relevant to me what
does and doesn't count as a definition.
> In any case, I think there is little danger of either of the declarations
> that you gave as examples being interpreted as definitions. That is why I
> believe the situation is different from the situation with parameter
> declarations.
Personally, I think parameter forward declarations are unclear in general: it's
not just computers, it's also us who need to scan ahead to know that the first
argument to a call to void f(int x, int y; int y, int x) is used for the
parameter y, not x. If we say that this is acceptable to users, if we expect
them to see the semicolon and realise that the initial int x, int y; are
forward declarations, I think we are already saying that there is little danger
of them being interpreted as definitions. If we instead say that that danger is
there, I think it would be difficult to justify using that danger *only* for
the purpose of diagnosing duplicate declarations, and not more generally.
> > They aren't. Because forward parameter declarations are never definitions,
> > there is no ambiguity.
>
> As far as I could tell from its source code, GCC provisionally treats
> parameter forward declarations as definitions, similar to how tentative
> definitions are provisionally treated as definitions. Have I misread the
> code, or is your opinion based on the intended semantics of GCC's extension?
> GCC's manual doesn't say anything about whether or not parameter forward
> declarations are definitions.
>
> I don't think the ISO C23 standard explicitly describes parameter
> declarations as definitions either; it just says "Each parameter has
> automatic storage duration; its identifier, if any, is an lvalue."
I'm going by the standard's meaning of "definition" in 6.7 Declarations, "A
definition of an identifier is a declaration for that identifier that for: an
object, causes storage to be reserved for that object". This applies to
parameter declarations but not to parameter forward declarations.
> Do you have any specific concerns about the proposed wording changes in
> https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3681.pdf ?
My objection is specifically about the rationale, not the wording, other than
that changes to the rationale might possibly lead to changes in desired
semantics, which would then result in changes to the wording.