Messages in this thread | | | Date | Sat, 20 Nov 2021 16:22:39 +0100 | Subject | 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)" <> |
| |
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/
| |