Re: [PATCH] Various pages: SYNOPSIS: Use VLA syntax in function parameters

Alejandro Colomar
2022-11-12T13:40:15Z

[-- Attachment #1.1: Type: text/plain, Size: 3876 bytes --]

Hi Joseph,

On 11/12/22 14:03, Joseph Myers wrote:
> On Sat, 12 Nov 2022, Alejandro Colomar via Gcc wrote:
>
>>> struct s { int a; };
>>> void f(int a, int b[((struct s) { .a = 1 }).a]);
>>
>> Is it really ambiguous? Let's show some currently-valid code:
>
> Well, I still don't know what the syntax addition you propose is. Is it
>
> postfix-expression : . identifier

I'll try to explain it in standardeese, but I'm not sure if I'll get it right,
so I'll accompany it with plain English.

Maybe Martin can help.

Since it's to be used as an rvalue, not as a lvalue, I guess a
postfix-expression wouldn't be the right one.

>
> (with a special rule about how the identifier is interpreted, different
> from the normal scope rules)? If so, then ".a = 1" could either match
> assignment-expression directly (assigning to the postfix-expression ".a").

No, assigning to a function parameter from within another parameter declaration
wouldn't make sense. They should be readonly. Side effects should be
forbidden, I think.

> Or it could match designation[opt] initializer, where ".a" is a
> designator. And as I've noted many times in discussions of C2x proposals
> on the WG14 reflector, if some sequence of tokens can match the syntax in
> more than one way, there always needs to be explicit normative text to
> disambiguate the intended parse - it's not enough that one parse might
> lead later to a violation of some other constraint (not that either parse
> leads to a constraint violation in this case).
>
> Or is the syntax
>
> array-declarator : direct-declarator [ . assignment-expression ]

Not good either. The '.' should prefix the identifier, not the expression. So,
for example, you would have:

void *bsearch(const void key[.size], const void base[.size * .nmemb],
size_t nmemb, size_t size,
int (*compar)(const void [.size], const void [.size]));

That's taken from the current manual page from git HEAD. See 'base', which gets
its size from the multiplication of 'size' and 'nmemb'.

>
> (with appropriate variants with static and type-qualifier-list and for
> array-abstract-declarator as well, and with different identifier
> interpretation rules inside the assignment-expression)? If so, then there
> are big problems parsing [ . ( a ) + ( b ) ], where 'a' is a typedef name
> in an outer scope, because the appropriate parse would depend on whether
> 'a' is shadowed by a parameter - unless of course you add appropriate
> wording like that present in some places about not being able to use this
> syntax to shadow a typedef name.
>
> Or is it just
>
> array-declarator : direct-declarator [ . identifier ]

For the initial implementation, it would be, I think.

>
> which might avoid some of these problems at the expense of being less
> expressive?

Yes.

>
> If you're proposing a C syntax addition, you always need to be clear about
> exactly what the new cases in the syntax would be, and how you resolve
> ambiguities with any other existing part of the syntax, how you interact
> with rules on scopes, namespaces and linkage of identifiers, etc.

Yeah, I'll try.

I think that the complete feature would allow 'designator' to be used within
unary-expression:

unary-expression: designator

Since sizeof(foo) is a unary-expression and you can't assign to it, I'm guessing
that similar rules could be used for '.size'.

That would have the effect of allowing both features suggested by Martin: being
able to used designators in both structures (as demonstrated in my last email)
and function prototypes (as in the thing we're discussing).

I hope I got it right. I'm not used to lexical grammar so much.

Cheers,

Alex