Hi Bruno, On Mon, Jun 02, 2025 at 02:32:46PM +0200, Bruno Haible wrote: > Hi Alejandro, > > > - I have plans for improving _Countof as a GNU extension to work on > > array parameters to functions. I mean making this possible: > > > > wchar_t * > > wmemset(size_t n; wchar_t wcs[n], wchar_t wc, size_t n) > > { > > for (size_t i = 0; i < countof(wcs); i++) > > wcs[i] = wc; > > return wcs; > > } > > The sizeof operator does not work well in this case, right? So that would be > a case where countof works _better_ than sizeof.
Yes, that's correct. _Countof will provide functionality that is not currently available in C programs at all. I believe this will make many of those complaints that people do that "C arrays are unsafe" be obsolete. > > What worries me of adding countof to C++ is that they may use it in > > some way that could preclude my planned extension. So I'll not > > remind C++ people about this until I made sure my extension is > > deployed in both GCC and Clang, and maybe in ISO C. > > While I understand this, it still means that gnulib — which strives to make > the same code usable in C++ like in C — will probably have to override > <stdcountof.h> roughly like this: > > #ifdef __cplusplus > template <typename T, size_t N> > constexpr size_t countof(T const (&)[N]) { > return N; > } > #else > # define countof _Countof > #endif You'll need to take into account the case where _Countof is not available, and fall back to sizeof division (which won't work with array parameters, but at least it will work in most cases). I'd do something like this: #ifdef __cplusplus template <typename T, size_t N> constexpr size_t countof(T const (&)[N]) { return N; } #elif __has_include(<stdcountof.h>) # include <stdcountof.h> #else # define countof(a) (sizeof(a) / sizeof((a)[0]) + must_be(is_array(a))) #endif must_be(is_array(a)) is a trick to assert that the argument is an array. <https://stackoverflow.com/questions/37538/how-do-i-determine-the-size-of-my-array-in-c/57537491#57537491> > (And I have no idea whether this definition will work for variable-sized > arrays and for function parameters.) I'm not sure if that C++ implementation would work with VLAs or array parameters. However, as long as it results in a compilation error, I'm not worried at all. What would worry me is if it would silently misbehave. I suggest that if you implement a countof alternative, you run the testsuite that I added in GCC for the operator. $ find gcc/testsuite/ | grep countof gcc/testsuite/gcc.dg/countof-pedantic.c gcc/testsuite/gcc.dg/countof-zero.c gcc/testsuite/gcc.dg/countof-no-compat.c gcc/testsuite/gcc.dg/countof-compat.c gcc/testsuite/gcc.dg/countof-vla.c gcc/testsuite/gcc.dg/countof-vmt.c gcc/testsuite/gcc.dg/countof.c gcc/testsuite/gcc.dg/countof-compile.c gcc/testsuite/gcc.dg/countof-pedantic-errors.c gcc/testsuite/gcc.dg/countof-stdcountof.c gcc/testsuite/gcc.dg/countof-zero-compile.c You should adapt them to test countof instead of _Countof, and you'll see the comment at the top to see which compiler flags are appropriate. If that testsuite passes, your implementation should be safe. A few things will not work with the sizeof division, as I'm testing that _Countof is smarter than that and makes some things be integer constant expressions where sizeof is unable to do that; but you can ignore those few test cases. Have a lovely day! Alex -- <https://www.alejandro-colomar.es/>
signature.asc
Description: PGP signature