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; }) | ^