Bruno Haible via Gnulib discussion list [2025-06-03 00:00 +0200] wrote:

> Alejandro Colomar wrote:
>>      # define countof(a) (sizeof(a) / sizeof((a)[0]) + must_be(is_array(a)))
>>      #endif
>> 
>> must_be(is_array(a)) is a trick to assert that the argument is an array.
>> <https://stackoverflow.com/questions/37538/how-do-i-determine-the-size-of-my-array-in-c/57537491#57537491>
>
> Now that is very nice! The ability to detect wrong use of function parameters
> is valuable already now. You referenced <https://lkml.org/lkml/2015/9/3/428>.

Thanks for this.
I'm facing an issue with _gl_verify_is_array in Clang, however.

I tried using Gnulib's countof macro for counting the number of
arguments passed to a variadic function, e.g.:

  #define CALL(fn, args) ((fn) (countof (args), (args)))
  #define CALLN(fn, ...) CALL (fn, ((int []) {__VA_ARGS__}))

This works with both GCC 14 and Clang 19 as long as __VA_ARGS__
comprises compile-time constants:

  CALLN (foo, 1, 2, 3);

However Clang fails to compile something like:

  CALLN (foo, rand(), rand(), rand());

with the precise diagnostics listed below.

Am I misunderstanding something or doing something wrong?

In case it helps, I'm compiling the following sample project:

0. git clone 'https://git.sr.ht/~blc/foo' && cd foo
1. ./bootstrap --skip-po && ./configure CC=clang && make

Thanks,
-- 
Basil

src/foo.c:23:26: error: initializer element is not a compile-time constant
   23 |   return FOO_CALLN (foo, rand(), rand(), rand());
      |                          ^~~~~~
src/foo.h:26:53: note: expanded from macro 'FOO_CALLN'
   26 | #define FOO_CALLN(fn, ...) FOO_CALL (fn, ((int []) {__VA_ARGS__}))
      |                                                     ^~~~~~~~~~~
src/foo.h:25:44: note: expanded from macro 'FOO_CALL'
   25 | #define FOO_CALL(fn, args) ((fn) (countof (args), (args)))
      |                                            ^~~~
./lib/stdcountof.h:35:70: note: expanded from macro 'countof'
   35 |   ((size_t) (sizeof (a) / sizeof ((a)[0]) + 0 * _gl_verify_is_array 
(a)))
      |                                                                      ^
./lib/stdcountof.h:87:104: note: expanded from macro '_gl_verify_is_array'
   87 |     sizeof (struct { unsigned int _gl_verify_error_if_negative : 
__builtin_types_compatible_p (typeof (a), typeof (&*(a))) ? -1 : 1; })
      |                                                                         
                               ^

Reply via email to