Messages in this thread |  | | Subject | Re: Expose 'array_length()' macro in <sys/param.h> | From | Alejandro Colomar <> | Date | Tue, 22 Sep 2020 12:35:21 +0200 |
| |
Thanks again for your improvements.
I think this might be ready for a patch already. Any more thoughts?
Thanks,
Alex
------------------------
#if defined(__cplusplus) # include <cstddef>
# if __cplusplus >= 201103L template<typename _Tp, std::size_t _Len> constexpr inline std::size_t __array_length(const _Tp(&)[_Len]) __THROW { return _Len; }
template<typename _Tp, std::size_t _Len> constexpr inline std::ptrdiff_t __array_slength(const _Tp(&)[_Len]) __THROW { return _Len; } # else /* __cplusplus < 201103L */ template<typename _Tp, std::size_t _Len> char (&__array_length(const _Tp(&)[_Len]))[_Len]; # define __array_length(_Arr) (sizeof(__array_length(_Arr))) # define __array_slength(_Arr) \ (static_cast<std::ptrdiff_t>(__array_length(_Arr))) # endif /* __cplusplus >= 201103L */
#else /* !defined(__cplusplus) */ #include <stddef.h>
# define __is_same_type(_A, _B) \ __builtin_types_compatible_p(__typeof__(_A), __typeof__(_B)) # define __is_array(_Arr) (!__is_same_type((_Arr), &(_Arr)[0]))
# 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!")
# define __array_len(_Arr) (sizeof(_Arr) / sizeof((_Arr)[0])) # define __array_length(_Arr) (__array_len(_Arr) + __must_be_array(_Arr)) # define __array_slength(_Arr) ((ptrdiff_t)__array_length(_Arr)) #endif /* defined(__cplusplus) */
static int a[5]; static int v[__array_slength(a)]; static int w[__array_length(v)]; static int *p;
int main(void) { int aa[5]; const int xx = 6; int vv[xx]; int yy = 7; int ww[yy]; int *pp;
(void)p; (void)pp; (void)ww;
return __array_slength(a) + __array_length(v) + __array_slength(w) /* + __array_length(p) */ /* Always breaks :) */ + __array_length(aa) + __array_slength(vv) + __array_length(ww) /* Not in C++ */ /* + __array_length(pp) */ /* Always breaks :) */ ; }
|  |