Hi Bruno, Paul, On Tue, Jun 03, 2025 at 11:52:04AM +0200, Bruno Haible wrote: > As written yesterday, the use of __SIZE_TYPE__ is wrong.
Agree; IMO, <stddef.h> is so fundamental, that anyone attempting to redefine anything from there is doomed. size_t should be considered a reserved keyword even without including any headers, even if the standards theoretically allow using that identifier if you don't include <stddef.h>. Have a lovely day! Alex > > And the "simplification" of sizeof ((a)[0]) to sizeof *(a) > is besides the point, because countof is about array elements and > the common syntax for accessing elements is array[index]. > > I'm therefore applying this patch: > > > 2025-06-03 Bruno Haible <br...@clisp.org> > > stdcountof-h: Always return size_t, in a better way. > * lib/stdcountof.in.h: Revert last change. Include <stddef.h> > unconditionally. > (countof): Cast value to size_t. > * tests/test-stdcountof-h.c (HAVE___TYPEOF__, HAVE__GENERIC): New > macros. > (test_func): Check the return type of countof. > > diff --git a/lib/stdcountof.in.h b/lib/stdcountof.in.h > index 6803b676bc..105cf209a5 100644 > --- a/lib/stdcountof.in.h > +++ b/lib/stdcountof.in.h > @@ -18,10 +18,8 @@ > #ifndef _GL_STDCOUNTOF_H > #define _GL_STDCOUNTOF_H > > -#ifndef __SIZE_TYPE__ > -# include <stddef.h> > -# define __SIZE_TYPE__ size_t > -#endif > +/* Get size_t. */ > +#include <stddef.h> > > /* Returns the number of elements of the array A, as a value of type size_t. > Example declarations of arrays: > @@ -33,7 +31,7 @@ > void func (int a[10]) { ... } > */ > #define countof(a) \ > - ((__SIZE_TYPE__) (sizeof (a) / sizeof *(a) + 0 * _gl_verify_is_array (a))) > + ((size_t) (sizeof (a) / sizeof ((a)[0]) + 0 * _gl_verify_is_array (a))) > > /* Attempts to verify that A is an array. */ > #if defined __cplusplus > @@ -55,7 +53,7 @@ template <typename T> > template <typename T> > struct _gl_array_type_test<T[]> { static const int is_array = 1; }; > /* Bounded arrays. */ > -template <typename T, __SIZE_TYPE__ N> > +template <typename T, size_t N> > struct _gl_array_type_test<T[N]> { static const int is_array = 1; }; > # define _gl_verify_is_array(a) \ > sizeof (_gl_verify_type<_gl_array_type_test<decltype(a)>::is_array>) > @@ -69,7 +67,7 @@ template <typename T> > template <typename T> > struct _gl_array_type_test<T[]> { char small; }; > /* Bounded arrays. */ > -template <typename T, __SIZE_TYPE__ N> > +template <typename T, size_t N> > struct _gl_array_type_test<T[N]> { char small; }; > /* The T& parameter is essential here: it prevents decay (array-to-pointer > conversion). */ > diff --git a/tests/test-stdcountof-h.c b/tests/test-stdcountof-h.c > index 619a666186..a382dc1b1e 100644 > --- a/tests/test-stdcountof-h.c > +++ b/tests/test-stdcountof-h.c > @@ -20,6 +20,25 @@ > > #include "macros.h" > > +/* Whether the compiler supports __typeof__. */ > +#if ((defined __GNUC__ && 2 <= __GNUC__) \ > + || (defined __clang_major__ && 4 <= __clang_major__) \ > + || (defined __IBMC__ && 1210 <= __IBMC__ && defined __IBM__TYPEOF__) \ > + || (defined __SUNPRO_C && 0x5110 <= __SUNPRO_C && !__STDC__) \ > + || (defined _MSC_VER && 1939 <= _MSC_VER)) > +# define HAVE___TYPEOF__ 1 > +#endif > + > +/* Whether the compiler supports _Generic. > + Test program: > + int f (int x) { return _Generic (x, char *: 2, int: 3); } > + */ > +#if (defined __GNUC__ && __GNUC__ + (__GNUC_MINOR__ >= 9) > 4) \ > + || (defined __clang__ && __clang_major__ >= 3) \ > + || (defined __SUNPRO_C && __SUNPRO_C >= 0x5150) > +# define HAVE__GENERIC 1 > +#endif > + > extern int integer; > extern int unbounded[]; > extern int bounded[10]; > @@ -47,6 +66,13 @@ test_func (int parameter[3]) > ASSERT (countof (integer) >= 0); > ASSERT (countof (unbounded) >= 0); > #endif > + > + /* Check that countof(...) is an expression of type size_t. */ > +#if !defined __cplusplus && HAVE___TYPEOF__ && HAVE__GENERIC > + ASSERT (_Generic (__typeof__ (countof (bounded)), size_t: 1, > default: 0)); > + ASSERT (_Generic (__typeof__ (countof (multidimensional)), size_t: 1, > default: 0)); > + ASSERT (_Generic (__typeof__ (countof (local_bounded)), size_t: 1, > default: 0)); > +#endif > } > > int > > > -- <https://www.alejandro-colomar.es/>
signature.asc
Description: PGP signature