Hi Bruno,

On Wed, Oct 08, 2025 at 12:47:43AM +0200, Bruno Haible wrote:
> >     $ make 
> >     make  all-recursive
> >     make[1]: Entering directory '/srv/alx/src/gnu/groff/master'
> >     make[2]: Entering directory '/srv/alx/src/gnu/groff/master'
> >       CXX      src/devices/grotty/tty.o
> >     In file included from src/devices/grotty/tty.cpp:26:
> >     ./lib/stdcountof.h: In instantiation of ‘struct _gl_verify_type<-1>’:
> >     src/devices/grotty/tty.cpp:751:27:   required from here
> >       751 |     const size_t buflen = countof("48;2;255;255;255m");
> >           |                           ^~~~~~~
> >     ./lib/stdcountof.h:55:18: error: negative width in bit-field 
> > ‘_gl_verify_type<-1>::_gl_verify_error_if_negative’
> >        55 |     unsigned int _gl_verify_error_if_negative: w;
> >           |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
> >     make[2]: *** [Makefile:10661: src/devices/grotty/tty.o] Error 1
> >     make[2]: Leaving directory '/srv/alx/src/gnu/groff/master'
> >     make[1]: *** [Makefile:13042: all-recursive] Error 1
> >     make[1]: Leaving directory '/srv/alx/src/gnu/groff/master'
> >     make: *** [Makefile:7452: all] Error 2
> 
> When we fix a bug, we always first need to reproduce it.

Yup; I guess.  I was hoping it would ring a bell to anyone more
experienced in C++ than I.

> The information you gave is not sufficient for allowing us to reproduce
> it. Please provide the following:
>   - The patch you are using, relative to groff's master branch.
>     Please provide it as an attachment, not inline in the mail,
>     because some mail providers mangle text outside of attachments.
>   - The platform (distro in case of the GNU/Linux system).
>   - The compiler (gcc or clang? which version?)
>   - The output of "make V=1". We need to see the compiler commands,
>     not some information-less shortcut.

I'll do something easier than giving you a large amount of patches.
Any string literal is rejected, as far as I can see.  I've pasted the
gnulib code in a small C++ file, removed the unused bits, and tried
compiling that instead:

        alx@devuan:~/tmp$ cat stdcountof.c++
        #include <stddef.h>

        /* Attempts to verify that A is an array.  */
        /* Borrowed from verify.h.  */
        template <int w>
          struct _gl_verify_type {
            unsigned int _gl_verify_error_if_negative: w;
          };
          /* Use decltype.  */
        /* Default case.  */
        template <typename T>
          struct _gl_array_type_test { static const int is_array = -1; };
        /* Unbounded arrays.  */
        template <typename T>
          struct _gl_array_type_test<T[]> { static const int is_array = 1; };
        /* Bounded arrays.  */
        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>)

        int
        main(void)
        {
                return _gl_verify_is_array("foo");
        }
        alx@devuan:~/tmp$ g++ --version
        g++ (Debian 15.2.0-4) 15.2.0
        Copyright (C) 2025 Free Software Foundation, Inc.
        This is free software; see the source for copying conditions.  There is 
NO
        warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR 
PURPOSE.

        alx@devuan:~/tmp$ g++ stdcountof.c++ 
        stdcountof.c++: In instantiation of ‘struct _gl_verify_type<-1>’:
        stdcountof.c++:25:9:   required from here
           20 |      sizeof 
(_gl_verify_type<_gl_array_type_test<decltype(a)>::is_array>)
              |                                                                 
        ^
        stdcountof.c++:7:18: error: negative width in bit-field 
‘_gl_verify_type<-1>::_gl_verify_error_if_negative’
            7 |     unsigned int _gl_verify_error_if_negative: w;
              |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~

> > I'm trying to use countof() in groff, and I'm having some issues I don't
> > understand.  groff is written in C++, which I don't understand, so the
> > issues might be due to something I just don't understand from C++, but
> > I think it's likely to be a bug in gnulib's implementation of the array
> > checker for C++.
> 
> Gnulib's <stdcountof.h> is meant to work in C++ mode. We actually have
> a unit test for that: gnulib/tests/test-stdcountof-h-c++.cc .

I've also added a patch to add this reproducer to the gnulib tests
(attached, as requested).


Have a lovely day!
Alex

-- 
<https://www.alejandro-colomar.es>
Use port 80 (that is, <...:80/>).
From 1cd8f4ab2483e8d6d15a1bce09d573a7a9bdd9ce Mon Sep 17 00:00:00 2001
Message-ID: <1cd8f4ab2483e8d6d15a1bce09d573a7a9bdd9ce.1759916950.git....@kernel.org>
From: Alejandro Colomar <[email protected]>
Date: Wed, 8 Oct 2025 11:40:58 +0200
Subject: [PATCH v1] stdcountof-h tests: Test a string literal

* tests/test-countof-h.c (test_func): Test a string literal.

Signed-off-by: Alejandro Colomar <[email protected]>
---
 ChangeLog                 | 5 +++++
 tests/test-stdcountof-h.c | 3 +++
 2 files changed, 8 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index b8f98a18ae..d5db8fc402 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2025-10-08  Alejandro Colomar  <[email protected]>
+
+	stdcountof-h tests: Test a string literal.
+	* tests/test-countof-h.c (test_func): Test a string literal.
+
 2025-10-03  Bruno Haible  <[email protected]>
 
 	localename-unsafe: Fix handling of yue-Hans locale on macOS.
diff --git a/tests/test-stdcountof-h.c b/tests/test-stdcountof-h.c
index b64bd9d58b..3abdf56561 100644
--- a/tests/test-stdcountof-h.c
+++ b/tests/test-stdcountof-h.c
@@ -46,11 +46,13 @@ test_func (int parameter[3])
   (void) _gl_verify_is_array (unbounded);
   (void) _gl_verify_is_array (bounded);
   (void) _gl_verify_is_array (multidimensional);
+  (void) _gl_verify_is_array ("string");
 #endif
 
   ASSERT (countof (bounded) == 10);
   ASSERT (countof (multidimensional) == 10);
   ASSERT (countof (local_bounded) == 20);
+  ASSERT (countof ("string") == 7);
 
 #if 0 /* These produce compilation errors.  */
 # ifdef _gl_verify_is_array
@@ -72,6 +74,7 @@ test_func (int parameter[3])
   ASSERT (_Generic (countof (bounded),          size_t: 1, default: 0));
   ASSERT (_Generic (countof (multidimensional), size_t: 1, default: 0));
   ASSERT (_Generic (countof (local_bounded),    size_t: 1, default: 0));
+  ASSERT (_Generic (countof ("string"),         size_t: 1, default: 0));
 #endif
 }
 
-- 
2.51.0

Attachment: signature.asc
Description: PGP signature

Reply via email to