https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121563

--- Comment #14 from Christopher Bazley <Chris.Bazley at arm dot com> ---
(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, 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.)

> 
> > 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.

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).

"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.

> Multiple declarations are valid in file scope and
> in function scope, so long as they are not definitions. It's just that your
> function scope example is a definition, whereas your file scope example is
> only a declaration (also a tentative definition, but that is not itself a
> definition). If we change it so that we have a non-definition and a
> definition at file scope, and a non-definition and a definition at function
> scope, we get a better comparison.
> 
> int x, x;         // declaration, okay
> int x = 1, x = 1; // multiple definition, error
> 
> void f() {
>     extern int x, x; // declaration, okay
>     int x, x;        // multiple definition, error
> }

Of course, but you have modified the declarations in such a way that they no
longer resemble one another. 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.

> > The main precedent for forward parameter declarations is tentative
> > definitions at file scope,
> 
> Multiple non-defining declarations being valid is the general rule,
> tentative definitions are not a special exception.
> 
>   typedef int x, x; // okay

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.

>   void f(), f(); // okay

"If the declaration of an identifier for a function has no storage-class
specifier, its linkage is determined exactly as if it were declared with the
storage-class specifier extern" (from the ISO standard). So, the only reason
this could be mistaken for a defining declaration is the fact that a
storage-class specifier is implicit.

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.

> > If the above declaration were allowed in function scope, it would be
> > ambiguous because it could be interpreted either as one declaration
> > shadowing another or as a redeclaration. Duplicate forward parameter
> > declarations are similarly ambiguous.
> 
> 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."

The C99 standard instead says "Each parameter has automatic storage duration.
Its identifier is an lvalue, which is in effect declared at the head of the
compound statement that constitutes the function body (and therefore cannot be
redeclared in the function body except in an enclosed block)." I suppose one
could deduce that an identifier that is "..in effect declared at the head of
the compound statement that constitutes the function body.." is probably a
definition (although not all such declarations are definitions, as you rightly
pointed out).

> The only reason forward parameter declarations are a special case is that we
> do not know yet at the end of the declarator whether the containing
> parameter-list is part of (to use your names) a parameter-declaration is
> part of a parameter-forward-declaration-list or of a parameter-type-list, we
> have to continue parsing until we reach the end of the parameter-declaration
> to make that determination. That may be justifiable as you and Alejandro
> also wrote for simplicity of implementation, but it should not be presented
> as anything more than that, in my opinion.

Do you have any specific concerns about the proposed wording changes in
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3681.pdf ?

Reply via email to