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

Alejandro Colomar
2022-11-10T10:09:49Z

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

Hi Joseph and Martin!

On 11/10/22 07:21, Martin Uecker wrote:
> Am Donnerstag, den 10.11.2022, 01:39 +0000 schrieb Joseph Myers:
>> On Thu, 10 Nov 2022, Joseph Myers wrote:
>>
>>> On Thu, 10 Nov 2022, Alejandro Colomar via Gcc wrote:
>>>
>>>> I've shown the three kinds of prototypes that have been changed:
>>>>
>>>> - Normal VLA; nothing fancy except for the '.'.
>>>> - Complex size expressions.
>>>> - 'void *' VLAs (assuming GNU conventions: sizeof(void *)==1).
>>>
>>> That doesn't cover any of the tricky issues with such proposals, such as
>>> the choice of which entity is referred to by the parameter name when there
>>> are multiple nested parameter lists that use the same parameter name, or
>>> when the identifier is visible from an outer scope (including in
>>> particular the case where it's declared as a typedef name in an outer
>>> scope).
>>
>> In fact I can't tell from these examples whether you mean for a '.' token
>> after '[' to have special semantics, or whether you mean to have a special
>> '. identifier' form of expression valid in certain context (each of which
>> introduces its own complications; for the former, typedef names from outer
>> scopes are problematic; for the latter, it's designated initializers where
>> you get complications, for example). Designing new syntax that doesn't
>> cause ambiguity is generally tricky, and this sort of language extension
>> is the kind of thing where you'd expect to so through at least five
>> iterations of a WG14 paper before you have something like a sound
>> specification.
>
> I am not sure what Alejandro has in mind exactly, but my idea of using
> a new notation [.identifier] would be to limit it to accessing other
> parameter names in the same parameter list only, so that there is
>
> 1) no ambiguity what is referred to and
> 2) one can access parameters which come later

Yes, I implemented your idea. As always, I thought I had linked to it in the
commit message, but I didn't. Quite a bad thing for the commit that implements
a completely new feature to not point to the documentation/idea at all.

So, the documentation followed by these 3 patches is Martin's email:
<https://lore.kernel.org/linux-man/601680ae-30d7-1481-e152-034083f6dde1@gmail.com/T/#med2bdfcc31a3d0b3bc6c48b229c8d8dd5088935e>

It was sound in my head, and I couldn't see any inconsistencies.

- I implemented it with '.' as being restricted to refer to parameters of the
function being prototypes (commit 1).

- I also allowed complex expressions in the prototypes (commit 2), since it's
something that can be quite useful (that was already foreseen by Martin's idea,
IIRC). The most useful example that I have in my mind is a patch that I'm
developing for shadow-utils:

<https://github.com/shadow-maint/shadow/pull/569/files#diff-12b560bab6b4fb8f7f3a16f01aaa994de539a8bed3058c976be0daebe16405c1>

The gist of it is a function that gets a fixed-width non-NUL-terminated
string, and copies it into a NUL-terminated string in a buffer than has to be of
course +1 the size of the input string:

void buf2str(char dst[restrict .n+1], const char src[restrict .n],
size_t n);

- I extended the idea to apply to void[] (commit 3). Something not yet allowed
by GCC, but very useful IMO, especially for the mem...(3) functions. Since GNU
C consistently treats sizeof(void)==1, it makes sense to allow VLA syntax in
that way. This is not at all about allowing true VLAs of type void[]; that's
forbidden, and should continue to be forbidden. But since parameters are just
pointers, I don't see any issue with allowing false void[] VLAs in parameters
that really are void* in disguise.

The 3 commits are here (last 3 commits in that log):
<https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/log/?id=c64cd13e002561c6802c6a1a1a8a640f034fea70>

Martin, please check if I implemented your idea faithfully. The 3 example
prototypes I showed are good representatives of what I added, so if you don't
understand man(7) source you could just read them and see if they make sense to
you; the rest of the changes are of the same kind. Or you could install the man
pages from the repo :)

>
> If we want to specify something like this, I think we should also
> restrict what kind of expressions one allows, e.g. it has to
> be side-effect free.

Well, yes, there should be no side effects; it would not make sense in a
prototype. I'd put it as simply as with _Generic(3) and similar stuff, where
the controlling expression is not evaluated for side effects. I never remember
about sizeof() or typeof(): I always need to consult if they have side effects
or not. I'll be documenting that in the man-pages soon.

> But maybe we want to make this even more
> restrictive (at least initially).

Yeah, you could go for an initial implementation that only supports my commit 1;
that would be the simplest. That would cover already the vast majority of
cases. But please consider commits 2 and 3 afterwards, since I believe they are
also of great importance.

>
> One problem with WG14 papers is that people put in too much,
> because the overhead is so high and the standard is not updated
> very often. It would be better to build such feature more
> incrementally, which could be done more easily with a compiler
> extension. One could start supporting just [.x] but not more
> complicated expressions.
>
> Later WG14 can still accept or reject or modify this proposal
> based on the experience we get.

Yeah, and I also think any WG14 papers with features as important as this one
without prior experience in a real compiler should be rejected. I don't think
it makes sense to standardize something just from theoretical discussions, and
force everyone to implement it afterwards. No matter how good the reviewers are.

>
> (I would also be happy with using GNU forward declarations, and
> I am not sure why people dislike them so much.)

For me, it's how easy it is to confuse a comma with a semicolon. Also,
unnecessarily long lines.

>
> Martin
Cheers,

Alex