These patches make use of the soon-to-be-standard countof() macro
instead of the traditional SIZEOF or ARRAY_CARDINALITY macros.


2026-03-02  Bruno Haible  <[email protected]>

        Use countof, part 2.
        Done through  sed -e 's/SIZEOF \([(][^()]*[)]\)/countof \1/g'
        * lib/boot-time.c: Include <stdcountof.h>.
        * lib/readutmp.c: Include <stdcountof.h>.
        * lib/boot-time-aux.h (get_linux_boot_time_fallback,
        get_openbsd_boot_time, get_windows_boot_time): Use countof.
        * lib/duplocale.c: Include <stdcountof.h>.
        (SIZEOF): Remove macro.
        (duplocale): Use countof instead.
        * lib/fatal-signal.c: Include <stdcountof.h>.
        (SIZEOF): Remove macro.
        (num_fatal_signals, actions_allocated): Use countof instead.
        * lib/iconv_open.c: Include <stdcountof.h>.
        (SIZEOF): Remove macro.
        (rpl_iconv_open): Use countof instead.
        * lib/term-style-control.c: Include <stdcountof.h>.
        (SIZEOF): Remove macro.
        (num_job_control_signals): Use countof instead.
        * lib/uniconv/u16-conv-to-enc.c: Include <stdcountof.h>.
        (SIZEOF): Remove macro.
        * lib/uniconv/u32-conv-to-enc.c: Include <stdcountof.h>.
        (SIZEOF): Remove macro.
        * lib/uniconv/u-conv-to-enc.h (FUNC): Use countof instead.
        * lib/uniconv/u16-strconv-to-enc.c: Include <stdcountof.h>.
        (SIZEOF): Remove macro.
        * lib/uniconv/u32-strconv-to-enc.c: Include <stdcountof.h>.
        (SIZEOF): Remove macro.
        * lib/uniconv/u-strconv-to-enc.h (FUNC): Use countof instead.
        * lib/uniname/uniname.c: Include <stdcountof.h>.
        (SIZEOF): Remove macro.
        (unicode_name_word, unicode_name_word_lookup, unicode_code_to_index,
        unicode_index_to_code, unicode_character_name, unicode_name_character):
        Use countof instead.
        * lib/uniwidth/width.c: Include <stdcountof.h>.
        (SIZEOF): Remove macro.
        (uc_width): Use countof instead.
        * lib/wait-process.c: Include <stdcountof.h>.
        (SIZEOF): Remove macro.
        (slaves_allocated): Use countof instead.
        * lib/gen-uni-tables.c (countof): Renamed from SIZEOF.
        * modules/boot-time (Depends-on): Add stdcountof-h.
        * modules/readutmp (Depends-on): Likewise.
        * modules/duplocale (Depends-on): Likewise.
        * modules/fatal-signal (Depends-on): Likewise.
        * modules/iconv_open (Depends-on): Likewise.
        * modules/term-style-control (Depends-on): Likewise.
        * modules/uniconv/u16-conv-to-enc (Depends-on): Likewise.
        * modules/uniconv/u32-conv-to-enc (Depends-on): Likewise.
        * modules/uniconv/u16-strconv-to-enc (Depends-on): Likewise.
        * modules/uniconv/u32-strconv-to-enc (Depends-on): Likewise.
        * modules/uniname/uniname (Depends-on): Likewise.
        * modules/uniwidth/width (Depends-on): Likewise.
        * modules/wait-process (Depends-on): Likewise.
        * tests/macros.h (SIZEOF): Remove macro.
        * tests/**/*.[hc]: Use countof instead of SIZEOF. Include <stdcountof.h>
        as needed.
        * modules/**/*-tests (Depends-on): Add stdcountof-h if needed.

        Use countof, part 1.
        * lib/argmatch.h: Include <stdcountof.h>.
        (ARRAY_CARDINALITY): Remove macro.
        (ARGMATCH_VERIFY): Use countof instead.
        * tests/test-argv-iter.c: Include <stdcountof.h>.
        (ARRAY_CARDINALITY): Remove macro.
        (main): Use countof instead.
        * tests/test-hash.c: Include <stdcountof.h>.
        (ARRAY_CARDINALITY): Remove macro.
        (main): Use countof instead.
        * tests/test-userspec.c: Include <stdcountof.h>.
        (ARRAY_CARDINALITY): Remove macro.
        (main): Use countof instead.
        * modules/argmatch (Depends-on): Add stdcountof-h.
        * modules/argv-iter-tests (Depends-on): Likewise.
        * modules/hash-tests (Depends-on): Likewise.
        * modules/userspec-tests (Depends-on): Likewise.

2026-03-02  Bruno Haible  <[email protected]>

        stdcountof-h: Improve comment.
        * lib/stdcountof.in.h (countof): Improve comment.

>From eeff8cae980509247ac701abf316f06758fc086f Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Mon, 2 Mar 2026 13:00:03 +0100
Subject: [PATCH 1/3] stdcountof-h: Improve comment.

* lib/stdcountof.in.h (countof): Improve comment.
---
 ChangeLog           | 5 +++++
 lib/stdcountof.in.h | 7 ++++++-
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index 7bbfb2f030..b4cc1ad2f4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2026-03-02  Bruno Haible  <[email protected]>
+
+	stdcountof-h: Improve comment.
+	* lib/stdcountof.in.h (countof): Improve comment.
+
 2026-03-02  Bruno Haible  <[email protected]>
 
 	Silence clang's -Wstring-plus-int warnings in Gnulib code.
diff --git a/lib/stdcountof.in.h b/lib/stdcountof.in.h
index cf3fc1e560..1422629bf2 100644
--- a/lib/stdcountof.in.h
+++ b/lib/stdcountof.in.h
@@ -39,13 +39,18 @@
 #include <stddef.h>
 
 /* Returns the number of elements of the array A, as a value of type size_t.
+
    Example declarations of arrays:
      extern int a[];
      extern int a[10];
      static int a[10][20];
      void func () { int a[10]; ... }
-   Attempts to produce an error if A is a pointer, e.g. in
+   It works for arrays that are declared outside functions and for local
+   variables of array type.  It does *not* work for function parameters
+   of array type, because they are actually parameters of pointer type.
+   In this case, i.e. if A is a pointer, e.g. in
      void func (int a[10]) { ... }
+   this macro attempts to produce an error.
  */
 #define countof(...) \
   ((size_t) (sizeof (__VA_ARGS__) / sizeof (__VA_ARGS__)[0] \
-- 
2.52.0

>From 8e2078774f51ea72fb8d770521d198b67b8b46b2 Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Mon, 2 Mar 2026 11:04:16 +0100
Subject: [PATCH 2/3] Use countof, part 1.

* lib/argmatch.h: Include <stdcountof.h>.
(ARRAY_CARDINALITY): Remove macro.
(ARGMATCH_VERIFY): Use countof instead.
* tests/test-argv-iter.c: Include <stdcountof.h>.
(ARRAY_CARDINALITY): Remove macro.
(main): Use countof instead.
* tests/test-hash.c: Include <stdcountof.h>.
(ARRAY_CARDINALITY): Remove macro.
(main): Use countof instead.
* tests/test-userspec.c: Include <stdcountof.h>.
(ARRAY_CARDINALITY): Remove macro.
(main): Use countof instead.
* modules/argmatch (Depends-on): Add stdcountof-h.
* modules/argv-iter-tests (Depends-on): Likewise.
* modules/hash-tests (Depends-on): Likewise.
* modules/userspec-tests (Depends-on): Likewise.
---
 ChangeLog               | 20 ++++++++++++++++++++
 lib/argmatch.h          |  6 ++----
 modules/argmatch        |  1 +
 modules/argv-iter-tests |  1 +
 modules/hash-tests      |  1 +
 modules/userspec-tests  |  1 +
 tests/test-argv-iter.c  |  5 ++---
 tests/test-hash.c       |  4 ++--
 tests/test-userspec.c   |  7 +++----
 9 files changed, 33 insertions(+), 13 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index b4cc1ad2f4..a3678eb889 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2026-03-02  Bruno Haible  <[email protected]>
+
+	Use countof, part 1.
+	* lib/argmatch.h: Include <stdcountof.h>.
+	(ARRAY_CARDINALITY): Remove macro.
+	(ARGMATCH_VERIFY): Use countof instead.
+	* tests/test-argv-iter.c: Include <stdcountof.h>.
+	(ARRAY_CARDINALITY): Remove macro.
+	(main): Use countof instead.
+	* tests/test-hash.c: Include <stdcountof.h>.
+	(ARRAY_CARDINALITY): Remove macro.
+	(main): Use countof instead.
+	* tests/test-userspec.c: Include <stdcountof.h>.
+	(ARRAY_CARDINALITY): Remove macro.
+	(main): Use countof instead.
+	* modules/argmatch (Depends-on): Add stdcountof-h.
+	* modules/argv-iter-tests (Depends-on): Likewise.
+	* modules/hash-tests (Depends-on): Likewise.
+	* modules/userspec-tests (Depends-on): Likewise.
+
 2026-03-02  Bruno Haible  <[email protected]>
 
 	stdcountof-h: Improve comment.
diff --git a/lib/argmatch.h b/lib/argmatch.h
index bfab000a44..0ff3d4effc 100644
--- a/lib/argmatch.h
+++ b/lib/argmatch.h
@@ -28,6 +28,7 @@
 # endif
 
 # include <limits.h>
+# include <stdcountof.h>
 # include <stddef.h>
 # include <stdio.h>
 # include <string.h> /* memeq */
@@ -39,14 +40,11 @@
 extern "C" {
 # endif
 
-# define ARRAY_CARDINALITY(Array) (sizeof (Array) / sizeof *(Array))
-
 /* Assert there are as many real arguments as there are values
    (argument list ends with a NULL guard).  */
 
 # define ARGMATCH_VERIFY(Arglist, Vallist) \
-    static_assert (ARRAY_CARDINALITY (Arglist) \
-                   == ARRAY_CARDINALITY (Vallist) + 1)
+    static_assert (countof (Arglist) == countof (Vallist) + 1)
 
 /* Return the index of the element of ARGLIST (NULL terminated) that
    matches with ARG.  If VALLIST is not NULL, then use it to resolve
diff --git a/modules/argmatch b/modules/argmatch
index 6532b38543..a80cffe179 100644
--- a/modules/argmatch
+++ b/modules/argmatch
@@ -17,6 +17,7 @@ memcmp
 quote
 quotearg
 bool
+stdcountof-h
 stdlib-h
 memeq
 streq
diff --git a/modules/argv-iter-tests b/modules/argv-iter-tests
index 9e0dfafc94..ddbc6a963a 100644
--- a/modules/argv-iter-tests
+++ b/modules/argv-iter-tests
@@ -4,6 +4,7 @@ tests/macros.h
 
 Depends-on:
 tmpfile
+stdcountof-h
 streq
 
 configure.ac:
diff --git a/modules/hash-tests b/modules/hash-tests
index 44d6382b5e..fd5db7c4ee 100644
--- a/modules/hash-tests
+++ b/modules/hash-tests
@@ -6,6 +6,7 @@ Depends-on:
 hashcode-string2
 inttostr
 bool
+stdcountof-h
 streq
 
 configure.ac:
diff --git a/modules/userspec-tests b/modules/userspec-tests
index 8b75be202d..d1d5a9dedf 100644
--- a/modules/userspec-tests
+++ b/modules/userspec-tests
@@ -3,6 +3,7 @@ tests/test-userspec.c
 
 Depends-on:
 xalloc
+stdcountof-h
 streq
 
 configure.ac:
diff --git a/tests/test-argv-iter.c b/tests/test-argv-iter.c
index db67b0ef81..ef205cbe5b 100644
--- a/tests/test-argv-iter.c
+++ b/tests/test-argv-iter.c
@@ -20,13 +20,12 @@
 
 #include "argv-iter.h"
 
+#include <stdcountof.h>
 #include <stdio.h>
 #include <string.h>
 
 #include "macros.h"
 
-#define ARRAY_CARDINALITY(Array) (sizeof (Array) / sizeof *(Array))
-
 static FILE *
 write_nul_delimited_argv (char **argv)
 {
@@ -58,7 +57,7 @@ main (void)
 
   for (int use_stream = 0; use_stream < 2; use_stream++)
     {
-      for (size_t i = 0; i < ARRAY_CARDINALITY (av); i++)
+      for (size_t i = 0; i < countof (av); i++)
         {
           FILE *fp;
           struct argv_iterator *ai;
diff --git a/tests/test-hash.c b/tests/test-hash.c
index 0bb9ca54ef..ffceee257b 100644
--- a/tests/test-hash.c
+++ b/tests/test-hash.c
@@ -21,6 +21,7 @@
 #include "hashcode-string2.h"
 #include "inttostr.h"
 
+#include <stdcountof.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -28,7 +29,6 @@
 
 #include "macros.h"
 
-#define ARRAY_CARDINALITY(Array) (sizeof (Array) / sizeof *(Array))
 
 static bool
 hash_compare_strings (void const *x, void const *y)
@@ -102,7 +102,7 @@ main (int argc, char **argv)
       srand (seed);
     }
 
-  for (unsigned int i = 0; i < ARRAY_CARDINALITY (table_size); i++)
+  for (unsigned int i = 0; i < countof (table_size); i++)
     {
       size_t sz = table_size[i];
       ht = hash_initialize (sz, NULL, hash_pjw, hash_compare_strings, NULL);
diff --git a/tests/test-userspec.c b/tests/test-userspec.c
index 61723e1261..b69b392702 100644
--- a/tests/test-userspec.c
+++ b/tests/test-userspec.c
@@ -20,6 +20,7 @@
 
 #include "userspec.h"
 
+#include <stdcountof.h>
 #include <stdio.h>
 #include <assert.h>
 #include <string.h>
@@ -30,8 +31,6 @@
 
 #include "xalloc.h"
 
-#define ARRAY_CARDINALITY(Array) (sizeof (Array) / sizeof *(Array))
-
 struct test
 {
   char in[100];
@@ -107,7 +106,7 @@ main (void)
       size_t len;
       if (!pw || !pw->pw_name || !(gr = getgrgid (pw->pw_gid)) || !gr->gr_name)
         continue;
-      j = ARRAY_CARDINALITY (T) - 1;
+      j = countof (T) - 1;
       len = strlen (pw->pw_name);
       if (sizeof T[j].in - 2 < len)
         continue;
@@ -127,7 +126,7 @@ main (void)
   char *user_name = NULL;
   char *group_name = NULL;
 
-  for (unsigned int i = 0; i < ARRAY_CARDINALITY (T); i++)
+  for (unsigned int i = 0; i < countof (T); i++)
     {
       uid_t uid = (uid_t) -1;
       gid_t gid = (gid_t) -1;
-- 
2.52.0

Attachment: 0003-Use-countof-part-2.patch.xz
Description: application/xz

Reply via email to