On 11/12/22 14:40, Alejandro Colomar wrote: > 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 Some mistake I did: Since enum designators don't make sense in this feature, it should only be: unary-expression: . identifier > > 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 > > --