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.) > 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. [...] > > 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)). > 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)). Arrays of length 0 exist, and should not be neglected by the standard. 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. > 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 -- <https://www.alejandro-colomar.es>
signature.asc
Description: PGP signature
