Am Montag, dem 15.12.2025 um 23:26 +0100 schrieb Alejandro Colomar:

Hi Alx,

> On Mon, Dec 15, 2025 at 09:51:50PM +0100, Martin Uecker wrote:
> > Am Montag, dem 15.12.2025 um 18:17 +0100 schrieb Alejandro Colomar:
> > > Hi Paul,
> > > 
> > > On Mon, Dec 15, 2025 at 08:47:36AM -0800, Paul Eggert wrote:
> > 
> > 
> > > 
> > > Then I don't see why gnulib would want to have this code:
> > > 
> > >   $ grepc -h -C1 VLA_ELEMS .
> > >   #ifdef __STDC_NO_VLA__
> > >   # define VLA_ELEMS(n)
> > >   #else
> > >   # define VLA_ELEMS(n) static n
> > >   #endif
> > > 
> > > Instead of just using
> > > 
> > >   #ifdef __STDC_NO_VLA__
> > >   # define VLA_ELEMS(n)
> > >   #else
> > >   # define VLA_ELEMS(n)  n
> > >   #endif
> > > 
> > > plus using __attribute__((__nonnull__())) appropriately.
> > 
> > The "just" goes into the wrong direction.
> > 
> > int foo(int n, char buf[static n]);
> > 
> > is nicer and simpler than
> > 
> > int foo(int n, char buf[n])
> >     __attribute__((__nonnull__(2));
> > 
> > which is uglier, non-standard, and error prone as you
> > need to count the arguments.   
> 
> You could ask GCC to implement Clang's [[gnu::nonnull]] which goes
> inside the parameter list.  That would remove the error-prone concerns.
> 
>       #define NONNULL  [[gnu::nonnull]]
> 
>       int foo(int n, NONNULL char buf[n]);
> 
> I'm pretty sure you wouldn't call that ugly or error-prone.  It is also
> C23 standard.

nonnull is not part of the C23 standard.   And even if GCC implemented
this (I complained that it should do this before), it would take years
until every GCC user can rely on it.  If we put the attribute into the next
C standard, it will be more like a decade.

> 
> > Also the former is required to be supported by all ISO C23 standards,
> > so there at least some hope that one could drop the #ifdef at some
> > point in the future (but probably you still need one for C++).
> 
> Hopefully not, because I pretend to remove [static n] from the standard.

It seems unlikely that you would succeed if you tried.


> Or are you intending to allow this?
> 
>       int bar(struct s *static p);
> 
> Or are you suggesting to use array notation even for non-array pointers?

You can do 

int bar(struct s p[static 1]);

if it points to a single object which semantically in C is an
array of size 1 for purposes of pointer arithmetic.

My suggestion would be to also allow

int bar(struct s p[static]);

if the length is unknown, but this would also be new.

I am also ok with having a [[nonnull]] attribute, but note that
"static" has stronger semantics that will become important in
the future as it implies that p can be safely dereferenced, and
I do not want to have to annotate my functions with three different
attributes in safe code.

In any case, even should we add an alternative to [static] I would
not support any proposal to remove it.  Backwards compatibility
is a major advantage of C. 

> 
> I'd prefer Clang's _Nullable keyword, if we're going to do that.

I prefer _Optional, because this works correctly.

> 
> > > Every compiler that "supports" (i.e., ignores) [static n] will similarly
> > > support (i.e., ignore) [n].  You're not getting any benefit from typing
> > > that extra keyword.
> > 
> > You do: You get warnings when you pass a null pointer, you get sanitizer
> > checking when you pass a null pointer, you get a warning if you compare
> > this argument against null, and you get optimizations based on the fact
> > that it is not null.
> 
> I awas assuming that you pass [[gnu::nonnull]] apart from using [n].
> You don't get any benefit with [[gnu::nonnull]] [n] vs [static n].

I assume you want say that [static n] has no advantages compared to
[[gnu::nonnull]] [n] for GCC.  This is true currently in terms of
what is implemented.   But [static n] is still better for all the
reasons explained above (and also pointed out by Paul in his email).
The stronger semantics of [static] could also allow even more warnings
in the future.

Martin





Reply via email to