Hi Paul, On Mon, Dec 15, 2025 at 12:50:14PM -0800, Paul Eggert wrote: > On 2025-12-15 09:17, Alejandro Colomar wrote: > > 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. > > First, some compilers support [static n] but lack support for > __attribute__((__nonnull__())), and it's useful to port well to these > compilers. One example is Oracle Developer Studio 12.6; I'm sure there are > others.
Hmmm, well, you could expand to [static n] for Oracle. But it would be
nice if for the usual compilers you use bare [n].
>
> Second, the VLA_ELEMS notation is shorter and easier to read as-is. For
> example, this:
>
> int
> main (int argc, char *argv[VLA_ELEMS (argc)])
> ...
>
> is easier to read than what I think you're proposing:
>
> int ATTRIBUTE_NONNULL ((2))
> main (int argc, char *argv[VLA_ELEMS (argc)])
> ...
I'd say the below is easier to read, as it's more explicit about the
nonnull-ness of the parameter. The fact that VLA_ELEMS() hides an
implicit nonnull is going to surprise programmers. The fact that it
hides an implicit n>0 is going to surprise programmers too.
As a side note, the attribute should go before the type:
ATTRIBUTE_NONNULL ((2))
int
main (int argc, char *argv[VLA_ELEMS (argc)])
...
(At least with C23's [[gnu::nonnull()]]; GNU C attribute syntax is more
forgiving.)
I often use precisely that syntax, where I use one line for the
attributes, one line for the storage-class specifiers and the type,
and another one for the identifier an parameter list.
Plus, since you're already using ATTRIBUTE_NONNULL() for non-array
parameters, it would be natural to also use it with array parameters.
BTW, out of curiosity, which compilers don't support [n] in function
parameters?
Have a lovely night!
Alex
> Here I am assuming Gnulib vla.h's definition of VLA_ELEMS (which you've
> quoted above) along with Gnulib attribute.h plus config.h's definitions,
> which are as follows (I have somewhat simplified, but it's still quite a
> portability mess, right? No wonder most C software developers run away from
> this stuff...):
>
> #if defined __GNUC__ && defined __GNUC_MINOR__ && !defined __clang__
> # define _GL_GNUC_PREREQ(major, minor) \
> ((major) < __GNUC__ + ((minor) <= __GNUC_MINOR__))
> #elif defined __clang__
> /* clang really only groks GNU C 4.2. */
> # define _GL_GNUC_PREREQ(major, minor) \
> ((major) < 4 + ((minor) <= 2))
> #else
> # define _GL_GNUC_PREREQ(major, minor) 0
> #endif
> #if (defined __has_attribute \
> && (!defined __clang_minor__ \
> || (defined __apple_build_version__ \
> ? 7000000 <= __apple_build_version__ \
> : 5 <= __clang_major__)))
> # define _GL_HAS_ATTRIBUTE(attr) __has_attribute (__##attr##__)
> #else
> # define _GL_HAS_ATTRIBUTE(attr) _GL_ATTR_##attr
> # define _GL_ATTR_nonnull _GL_GNUC_PREREQ (3, 3)
> /* ... */
> #endif
> #if _GL_HAS_ATTRIBUTE (nonnull)
> # define _GL_ATTRIBUTE_NONNULL(args) __attribute__ ((__nonnull__ args))
> #else
> # define _GL_ATTRIBUTE_NONNULL(args)
> #endif
> #define ATTRIBUTE_NONNULL(args) _GL_ATTRIBUTE_NONNULL (args)
--
<https://www.alejandro-colomar.es>
signature.asc
Description: PGP signature
