gbranden pushed a commit to branch master
in repository groff.

commit dd517efbb99e8dba75e23b5c750b41b3af284670
Author: G. Branden Robinson <g.branden.robin...@gmail.com>
AuthorDate: Sat Jul 12 16:38:35 2025 -0500

    [troff]: Favor C++ cast operators over those of C.
    
    * src/roff/troff/input.cpp (print_macros, get_flags)
      (charinfo::get_flags): Use explicit `reinterpret_cast` C++ operator
      instead of C-style cast.  Annotate why we use this footgun.
    
    Annotate every other use of `reinterpret_cast` in GNU troff, too.
    
    Also annotate null pointers with `nullptr` comment to ease any future
    transition to C++11, which defines it as a keyword.
---
 ChangeLog                |  7 +++++++
 src/roff/troff/env.cpp   |  2 ++
 src/roff/troff/input.cpp | 26 ++++++++++++++++++--------
 src/roff/troff/node.cpp  |  2 ++
 src/roff/troff/reg.cpp   |  2 ++
 5 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f698f8ea4..39f31ea4a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2025-07-12  G. Branden Robinson <g.branden.robin...@gmail.com>
+
+       * src/roff/troff/input.cpp (print_macros, get_flags)
+       (charinfo::get_flags): Use explicit `reinterpret_cast` C++
+       operator instead of C-style cast.  Annotate why we use this
+       footgun.
+
 2025-07-12  G. Branden Robinson <g.branden.robin...@gmail.com>
 
        * tmac/eqnrc: Drop unneccessary setup.  Since commit 4b3e5417d5,
diff --git a/src/roff/troff/env.cpp b/src/roff/troff/env.cpp
index fdf435877..2b28ec9e5 100644
--- a/src/roff/troff/env.cpp
+++ b/src/roff/troff/env.cpp
@@ -3858,6 +3858,8 @@ static void print_hyphenation_exceptions()
   // space; see `hyphen_trie::read_patterns_file()`.
   const size_t bufsz = WORD_MAX * 2;
   char wordbuf[bufsz]; // need to `errprint()` it, so not `unsigned`
+  // We must use the nuclear `reinterpret_cast` operator because GNU
+  // troff's dictionary types use a pre-STL approach to containers.
   while (iter.get(&entry, reinterpret_cast<void **>(&hypoint))) {
     assert(!entry.is_null());
     assert(hypoint != 0 /* nullptr */);
diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp
index 4bdebd4c5..88846d79d 100644
--- a/src/roff/troff/input.cpp
+++ b/src/roff/troff/input.cpp
@@ -1591,6 +1591,8 @@ static void report_color()
   }
   else {
     dictionary_iterator iter(color_dictionary);
+    // We must use the nuclear `reinterpret_cast` operator because GNU
+    // troff's dictionary types use a pre-STL approach to containers.
     while (iter.get(&key, reinterpret_cast<void **>(&value))) {
       assert(!key.is_null());
       assert(value != 0 /* nullptr */);
@@ -3796,7 +3798,9 @@ void print_macros()
   }
   else {
     object_dictionary_iterator iter(request_dictionary);
-    while (iter.get(&s, (object **)&rm)) {
+    // We must use the nuclear `reinterpret_cast` operator because GNU
+    // troff's dictionary types use a pre-STL approach to containers.
+    while (iter.get(&s, reinterpret_cast<object **>(&rm))) {
       assert(!s.is_null());
       m = rm->to_macro();
       if (m != 0 /* nullptr */) {
@@ -4451,6 +4455,8 @@ static void report_composite_characters()
   dictionary_iterator iter(composite_dictionary);
   symbol key;
   char *value;
+  // We must use the nuclear `reinterpret_cast` operator because GNU
+  // troff's dictionary types use a pre-STL approach to containers.
   while (iter.get(&key, reinterpret_cast<void **>(&value))) {
     assert(!key.is_null());
     assert(value != 0 /* nullptr */);
@@ -5413,11 +5419,11 @@ void substring_request()
        string_iterator iter(*m);
        int i;
        for (i = 0; i < start; i++) {
-         int c = iter.get(0);
+         int c = iter.get(0 /* nullptr */);
          while (c == PUSH_GROFF_MODE
                 || c == PUSH_COMP_MODE
                 || c == POP_GROFFCOMP_MODE)
-           c = iter.get(0);
+           c = iter.get(0 /* nullptr */);
          if (c == EOF)
            break;
        }
@@ -5428,7 +5434,7 @@ void substring_request()
          while (c == PUSH_GROFF_MODE
                 || c == PUSH_COMP_MODE
                 || c == POP_GROFFCOMP_MODE)
-           c = iter.get(0);
+           c = iter.get(0 /* nullptr */);
          if (c == EOF)
            break;
          if (c == 0)
@@ -6453,7 +6459,7 @@ void device_extension_node::tprint(troff_output_file *out)
   tprint_start(out);
   string_iterator iter(mac);
   for (;;) {
-    int c = iter.get(0);
+    int c = iter.get(0 /* nullptr */);
     if (c != EOF)
       for (const char *s = ::asciify(c); *s != 0 /* nullptr */; s++)
        tprint_char(out, *s);
@@ -7861,7 +7867,7 @@ void write_macro_request()
   else {
     string_iterator iter(*m);
     for (;;) {
-      int c = iter.get(0);
+      int c = iter.get(0 /* nullptr */);
       if (c == EOF)
        break;
       fputs(asciify(c), fp);
@@ -10216,7 +10222,9 @@ void get_flags()
   dictionary_iterator iter(charinfo_dictionary);
   charinfo *ci;
   symbol s;
-  while (iter.get(&s, (void **)&ci)) {
+  // We must use the nuclear `reinterpret_cast` operator because GNU
+  // troff's dictionary types use a pre-STL approach to containers.
+  while (iter.get(&s, reinterpret_cast<void **>(&ci))) {
     assert(!s.is_null());
     ci->get_flags();
   }
@@ -10229,7 +10237,9 @@ void charinfo::get_flags()
   dictionary_iterator iter(char_class_dictionary);
   charinfo *ci;
   symbol s;
-  while (iter.get(&s, (void **)&ci)) {
+  // We must use the nuclear `reinterpret_cast` operator because GNU
+  // troff's dictionary types use a pre-STL approach to containers.
+  while (iter.get(&s, reinterpret_cast<void **>(&ci))) {
     assert(!s.is_null());
     if (ci->contains(get_unicode_code())) {
 #if defined(DEBUGGING)
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index 3b90837c9..7ab47a47e 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -6646,6 +6646,8 @@ static void dump_font_translations()
 {
   dictionary_iterator iter(font_translation_dictionary);
   symbol from, to;
+  // We must use the nuclear `reinterpret_cast` operator because GNU
+  // troff's dictionary types use a pre-STL approach to containers.
   while (iter.get(&from, reinterpret_cast<void **>(&to)))
     errprint("%1\t%2\n", from.contents(), to.contents());
   fflush(stderr);
diff --git a/src/roff/troff/reg.cpp b/src/roff/troff/reg.cpp
index 9de106b85..f8f39af53 100644
--- a/src/roff/troff/reg.cpp
+++ b/src/roff/troff/reg.cpp
@@ -577,6 +577,8 @@ void dump_register_request()
   }
   else {
     object_dictionary_iterator iter(register_dictionary);
+    // We must use the nuclear `reinterpret_cast` operator because GNU
+    // troff's dictionary types use a pre-STL approach to containers.
     while (iter.get(&identifier, reinterpret_cast<object **>(&r))) {
       assert(!identifier.is_null());
       dump_register(&identifier, r);

_______________________________________________
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit

Reply via email to