Hi Alex,

Am Dienstag, dem 16.12.2025 um 13:17 +0100 schrieb Alejandro Colomar:
> Hi Martin,
> 
> On Tue, Dec 16, 2025 at 08:06:44AM +0100, Martin Uecker wrote:
> > Am Montag, dem 15.12.2025 um 23:26 +0100 schrieb Alejandro Colomar:
> > >   #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.
> 
> Every [[]] attribute, including [[no_such_attribute]], is part of the
> C23 standard.  A compiler is required to accept it as valid.  Whether it
> will ignore it or not is a matter of QoI.  (I have my own concerns about
> this, of course, but that's the standard we have now.)

Yes, in this sense it is allowed, but this does not solve the problem.
> 
> > 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.
> 
> GCC is required by C23 to accept [[gnu::nonnull]] within a parameter
> list.  And indeed, GCC supports this placement since years ago already.
> Of course, it diagnoses and ignores.  That's the right thing to do with
> an attribute that is not understood, IMO (and something which should
> also be standard).
> 
> So, we're not talking about decades; we're talking that some programs
> could start using [[gnu::nonnull]] in parameter lists as soon as they
> are able to use C23 attributes.

But who would want to add such attributes if they cause a lot of
unnecessariy warnings on most existing compilers?   Also you need to
adapt to each compiler with a prefix gnu / clang.  With attributes
you always need complicated #ifdef logic for a long time.

> 
> [...]
> 
> > > 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.
> 
> I know.  My point was that it isn't exactly good for readability.
> On the other hand, I'm reconsidering...  Maybe it would be good, as it
> says there's exactly one element, as opposed to raw pointers, which
> could be left exclusively for when you need to do pointer arithmetic
> and don't want to inform the compiler (maybe because you'll go
> off-bounds on purpose, such as when implementing free(3)).

I find it very readable.  Sure,  [static] is not self-explanatory, so
if you do not know it you need to read up on it once.  This is an
advantage of nonnull (but not of the current GCC version), but only
a very small one.   Not nearly enough to avoid [static] that every
conforming C compiler has to support for the last 25 years.

> 
> > 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'm relatively okay with that.  I don't like 'static', but if we'll have
> it, we should have consistency.
> 
> > 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
> 
> This is not "stronger semantic".  This is pure brain damage.  Probably
> the worst of all the bad semantics of 'static'.  The implication that
> n > 0 is terrible.  It means you can't use [static n] if n might be 0,
> which does happen in APIs (think of wmemcpy(3)).

I do not understand why you think static implies n > 0.  The problem
here is that arrays of zero length are not supported by the standard,
but this is true also without "static".
> 
> Arrays of length 0 exist, and should not be neglected by the standard.

In general I agree.
> 
> What's the purpose of knowing you can safely access [0]?!
> You already know you can safely access every ith element where i>=0 and
> i<n.  You should make sure to access exclusively that range, and no
> more.  It the range has 0 elements, you should access no elements.
> The desire to access element 0 is not based on any logic.  That's the
> same kind of brain damage that first made malloc(3) unrealiable, and
> which got us with the even-more-broken realloc(3).
> 
> > I do not want to have to annotate my functions with three different
> > attributes in safe code.
> 
> You should not annotate that n>0 in any way.  That should be never
> needed.

This is not what I meant.  [static n] implies that for all offsets 
0 <= i < n you can dereference the pointer.  This is stronger than
nonnull, e.g. it also implies that the pointer has the correct type.

Martin



> > 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. 
> 
> The thing about [static] is that it's a UB bomb.
>
> The other thing is that it's so little used that we might be able to get
> rid of it.
> 
> Compilers will keep allowing it, anyway, for backwards compatibility.
> 
> > > I'd prefer Clang's _Nullable keyword, if we're going to do that.
> > 
> > I prefer _Optional, because this works correctly.
> 
> Me too.
> 
> 
> Have a lovely day!
> Alex

Reply via email to