This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Using array_length macro outside function


On 2/4/19 6:34 AM, Florian Weimer wrote:

> +#define array_length(var)                                       \
> +  (sizeof (var) / sizeof ((var)[0])                             \
> +   + 0 * sizeof (struct { int ARGUMENT_NOT_AN_ARRAY:            \
> +       1 - (__builtin_types_compatible_p                        \
> +            (__typeof (var), __typeof (&(var)[0]))); }))

In Gnulib apps we've needed static assertions in expressions so often that we have a macro 'verify_expr (R, E)' that means "verify R statically, and yield the value of E". With this macro, you could rewrite the above definition as:

  #define array_length(var)                                             \
    verify_expr (!__builtin_types_compatible_p (__typeof (var),         \
                                                __typeof (&(var)[0])),  \
                 sizeof (var) / sizeof ((var)[0]))

which is quite a bit easier to follow. So I suggest appending something like the following to include/verify.h:

  #define verify_expr(r, e) \
    (sizeof (struct { _Static_assert (r, #r); char __dummy; }) \
     ? (e) : (e))

Then we can have array_length.h include verify.h and use the abovementioned simpler array_length.

(The Gnulib verify_expr caters to non-GNU and pre-C99 compilers and so is more complicated, but we don't need that complexity in glibc.)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]