Re: [PATCH v2 12/20] linux/must_be.h: Add must_be() to improve readability of BUILD_BUG_ON_ZERO()

From: Alejandro Colomar (man-pages)
Date: Sat Nov 20 2021 - 10:22:48 EST


Hi Alexey,

On 11/20/21 16:05, Alexey Dobriyan wrote:
> On Sat, Nov 20, 2021 at 02:00:55PM +0100, Alejandro Colomar wrote:
>> Historically, BUILD_BUG_ON_ZERO() has been hard to read.
>> __must_be_array() is based on BUILD_BUG_ON_ZERO(),
>> and unlike BUILD_BUG_ON_*(),
>> it has a pretty readable name.
>
> The best name is assert() which userspace uses and is standartised.

Yes, assert() is almost the same thing.
In this case, it would be better named static_assert(),
since it's a compile-time assert().

However,
there's still one slight difference
between static_assert() and must_be():

static_assert() is limited;
it cannot be used in some places,
such as in the implementation of ARRAY_SIZE().
The following doesn't compile:

#define __arraycount(a) (sizeof((arr)) / sizeof((arr)[0])
#define ARRAY_SIZE(a) (__arraycount(a) + static_assert(is_array(a)))

And if you change it to be:

#define ARRAY_SIZE(a) ( \
{ \
static_assert(is_array(a)); \
__arraycount(a); \
} \
)

then the macro can't be used at file scope
(since ({}) can't be used at file scope).

The good thing about __must_be() is that it evaluates to 0,
which allows you to use it
everywhere a 0 can be used.

My own implementation of __must_be() is
more standards compliant,
and is:

#define must_be(e) ( \
0 * (int)sizeof( \
struct { \
static_assert(e); \
char ISO_C_forbids_a_struct_with_no_members__; \
} \
) \
)

I would like this to superseed
the kernel's BUILD_BUG_ON_ZERO(),
but it makes use of C2X static_assert().
I don't know how much that can be a problem.

But please consider this proposal.

Thanks,
Alex


--
Alejandro Colomar
Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/