Subject: Re: bug#78933: compilation error after recent 'od' changes
From: Paul Eggert <[email-masked]>
To: Bruno Haible <[email-masked]>
Cc: [email-masked]
Date: Mon, 30 Jun 2025 15:43:33 -0700
List-Id: <debbugs-submit.debbugs.gnu.org>

On 2025-06-30 12:47, Bruno Haible via GNU coreutils Bug Reports wrote:

>    162 | static_assert (ARRAY_CARDINALITY (width_bytes) == N_SIZE_SPECS);
>        | ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Thanks for reporting that. I installed the attached to fix it.

From 48281e56a399818fa6326b6519f1ba3d8b7d5488 Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Mon, 30 Jun 2025 15:40:57 -0700
Subject: [PATCH] od: port to Apple clang 14
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* src/od.c (print_function_type): New type.  Use it for convenience.
(width_bytes): Omit duplicate entries, such as ‘double’ vs ‘long
double’ on macOS.  Problem reported by Bruno Haible
<https://bugs.gnu.org/78933>.
(decode_one_format): Cast null pointer to print_function_type
to pacify Apple clang-1400.0.29.202.
---
 src/od.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/src/od.c b/src/od.c
index 24e981cb0..b64f083c6 100644
--- a/src/od.c
+++ b/src/od.c
@@ -109,18 +109,21 @@ enum
 /* Ensure that our choice for FMT_BYTES_ALLOCATED is reasonable.  */
 static_assert (MAX_INTEGRAL_TYPE_WIDTH <= 3 * 99);
 
+/* The type of a print function.  FIELDS is the number of fields per
+   line, BLANK is the number of fields to leave blank.  WIDTH is width
+   of one field, excluding leading space, and PAD is total pad to
+   divide among FIELDS.  PAD is at least as large as FIELDS.  */
+typedef void (*print_function_type)
+  (idx_t fields, idx_t blank, void const *data,
+   char const *fmt, int width, idx_t pad);
+
 /* Each output format specification (from '-t spec' or from
    old-style options) is represented by one of these structures.  */
 struct tspec
   {
     enum output_format fmt;
     enum size_spec size; /* Type of input object.  */
-    /* FIELDS is the number of fields per line, BLANK is the number of
-       fields to leave blank.  WIDTH is width of one field, excluding
-       leading space, and PAD is total pad to divide among FIELDS.
-       PAD is at least as large as FIELDS.  */
-    void (*print_function) (idx_t fields, idx_t blank, void const *data,
-                            char const *fmt, int width, idx_t pad);
+    print_function_type print_function;
     char fmt_string[FMT_BYTES_ALLOCATED]; /* Of the style "%*d".  */
     bool hexl_mode_trailer;
     int field_width; /* Minimum width of a field, excluding leading space.  */
@@ -152,9 +155,13 @@ static const int width_bytes[] =
 #elif FLOAT16_SUPPORTED
   sizeof (float16),
 #endif
+#if FLT_MANT_DIG < DBL_MANT_DIG || FLT_MAX_EXP < DBL_MAX_EXP
   sizeof (float),
+#endif
   sizeof (double),
-  sizeof (long double)
+#if DBL_MANT_DIG < LDBL_MANT_DIG || DBL_MAX_EXP < LDBL_MAX_EXP
+  sizeof (long double),
+#endif
 };
 
 /* Ensure that for each member of 'enum size_spec' there is an
@@ -709,8 +716,7 @@ decode_one_format (char const *s_orig, char const *s, char const **next,
   enum size_spec size_spec;
   int size;
   enum output_format fmt;
-  void (*print_function) (idx_t, idx_t, void const *, char const *,
-                          int, idx_t);
+  print_function_type print_function;
   char const *p;
   char c;
   int field_width;
@@ -822,7 +828,7 @@ decode_one_format (char const *s_orig, char const *s, char const **next,
            ? print_intmax
            : LONG < LONG_LONG && LONG_LONG < INTMAX && size_spec == LONG_LONG
            ? print_long_long
-           : (affirm (false), nullptr));
+           : (affirm (false), (print_function_type) nullptr));
       break;
 
     case 'f':
-- 
2.48.1