lkml.org 
[lkml]   [2020]   [Nov]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    SubjectPing(3): [PATCH v4] <sys/param.h>: Add nitems()
    From
    Date
    Hi,

    Do you think the patch is ready,
    or is there anything else I should do before merging it?

    Thanks,

    Alex

    On 9/28/20 9:12 PM, Alejandro Colomar wrote:
    > 'nitems()' calculates the length of an array in number of items.
    > It is safe: if a pointer is passed to the macro (or function, in C++),
    > the compilation is broken due to:
    > - In >= C11: _Static_assert()
    > - In C89, C99: Negative anonymous bitfield
    > - In C++: The template requires an array
    >
    > Some BSDs already provide a macro nitems() in <sys/param.h>,
    > although it usually doesn't provide safety against pointers.
    >
    > This patch uses the same name for compatibility reasons,
    > and to be the least disruptive with existing code.
    >
    > This patch also adds some other macros, which are required by 'nitems()':
    >
    > __is_same_type(a, b):
    > Returns non-zero if the two input arguments are of the same type.
    >
    > __is_array(arr):
    > Returns non-zero if the input argument is of an array type.
    >
    > __must_be(expr, msg):
    > Allows using _Static_assert() everywhere an expression can be used.
    > It evaluates '(int)0' or breaks the compilation.
    >
    > __must_be_array(arr):
    > It evaluates to '(int)0' if the argument is of an array type.
    > Else, it breaks compilation.
    >
    > __nitems(arr):
    > It implements the basic sizeof division needed to calculate the array length.
    >
    >
    > P.S.: I'd like to put this patch in the public domain.
    >
    > Signed-off-by: Alejandro Colomar <colomar.6.4.3@gmail.com>
    > ---
    >
    > A few changes since v3:
    >
    > - Macros don't need reserved names in their parameters,
    > so I simplified those names.
    >
    > - I fixed some wrong indentation levels.
    >
    > - Renamed __array_len() to __nitems() for consistency.
    >
    >
    > misc/sys/param.h | 47 +++++++++++++++++++++++++++++++++++++++++++++++
    > 1 file changed, 47 insertions(+)
    >
    > diff --git a/misc/sys/param.h b/misc/sys/param.h
    > index d7c319b157..08d4093961 100644
    > --- a/misc/sys/param.h
    > +++ b/misc/sys/param.h
    > @@ -102,5 +102,52 @@
    > #define MIN(a,b) (((a)<(b))?(a):(b))
    > #define MAX(a,b) (((a)>(b))?(a):(b))
    >
    > +/* Macros related to the types of variables */
    > +#define __is_same_type(a, b) \
    > + __builtin_types_compatible_p(__typeof__(a), __typeof__(b))
    > +#define __is_array(arr) (!__is_same_type((arr), &(arr)[0]))
    > +
    > +/* Macros for embedding _Static_assert() in expressions */
    > +#if __STDC_VERSION__ >= 201112L
    > +# define __must_be(expr, msg) ( \
    > + 0 * (int)sizeof( \
    > + struct { \
    > + _Static_assert((expr), msg); \
    > + char _ISO_C_forbids_a_struct_with_no_members; \
    > + } \
    > + ) \
    > +)
    > +#else
    > +# define __must_be(expr, msg) ( \
    > + 0 * (int)sizeof( \
    > + struct { \
    > + int : (-!(expr)); \
    > + char _ISO_C_forbids_a_struct_with_no_members; \
    > + } \
    > + ) \
    > +)
    > +#endif
    > +#define __must_be_array(arr) __must_be(__is_array(arr), "Must be an array!")
    > +
    > +/* Macros for array sizes */
    > +#if defined(__cplusplus)
    > +# if __cplusplus >= 201103L
    > +template<typename _Tp, std::size_t _Len>
    > + constexpr inline std::size_t
    > + nitems(const _Tp(&)[_Len]) __THROW
    > + {
    > + return _Len;
    > + }
    > +# else /* __cplusplus < 201103L */
    > +template<typename _Tp, std::size_t _Len>
    > + char
    > + (&__nitems_chararr(const _Tp(&)[_Len]))[_Len];
    > +# define nitems(arr) (sizeof(__nitems_chararr(arr)))
    > +# endif /* __cplusplus < 201103L */
    > +#else /* !defined(__cplusplus) */
    > +# define __nitems(arr) (sizeof((arr)) / sizeof((arr)[0]))
    > +# define nitems(arr) (__nitems(arr) + __must_be_array(arr))
    > +#endif /* !defined(__cplusplus) */
    > +
    >
    > #endif /* sys/param.h */
    >

    \
     
     \ /
      Last update: 2020-11-17 23:25    [W:2.526 / U:0.496 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site