I'm trying to use module 'getopt-gnu' in a C++ program that has a global
variable named 'option'. There are compilation errors due to confusion
between 'option' and 'rpl_option'.

Our usual replacement technique
  #define foo rpl_foo
is usually fine for functions names, because hardly any program has a
global variable defined with the same name as a function. But for
struct names it's different, since in C struct names are in a different
namespace. Overrides of 'struct stat' or 'struct mbstate_t' are hairy
enough, but 'struct option' is even worse because programmers are
tempted to use 'option' as a variable or parameter name.

This patch fixes the trouble by instead renaming the system's
'struct option' to 'struct sys_option'. This is an idiom that we haven't
used so far and that can also cause trouble. But I think that here it
is less likely to cause trouble (because 1. 'struct option' is only used
in <getopt.h>, and very few source files ever include <getopt.h>, 2.
different compilation units are unlikely to access the same 'struct option'
object).


2025-04-16  Bruno Haible  <br...@clisp.org>

        getopt-posix: Avoid trouble due to 'struct rpl_option'.
        * lib/getopt.in.h: Arrange for the system's <getopt.h> to define
        'struct sys_option' instead of 'struct option'.
        * lib/getopt-pfx-ext.h (option): Don't rename to rpl_option.

diff --git a/lib/getopt-pfx-ext.h b/lib/getopt-pfx-ext.h
index 1f2b2d71bf..a61c68c795 100644
--- a/lib/getopt-pfx-ext.h
+++ b/lib/getopt-pfx-ext.h
@@ -38,11 +38,9 @@
 # endif
 # undef getopt_long
 # undef getopt_long_only
-# undef option
 # undef _getopt_internal
 # define getopt_long __GETOPT_ID (getopt_long)
 # define getopt_long_only __GETOPT_ID (getopt_long_only)
-# define option __GETOPT_ID (option)
 # define _getopt_internal __GETOPT_ID (getopt_internal)
 
 /* The system's getopt.h may have already included getopt-ext.h to
diff --git a/lib/getopt.in.h b/lib/getopt.in.h
index 79200ecdab..4a87a2d53b 100644
--- a/lib/getopt.in.h
+++ b/lib/getopt.in.h
@@ -30,7 +30,12 @@
    <getopt.h>; our definitions will be present soon enough.  */
 #if @HAVE_GETOPT_H@
 # define _GL_SYSTEM_GETOPT
+/* Rename the system's 'struct option' to 'struct sys_option',
+   so that we don't have to rename ours to 'struct rpl_option'
+   (which would cause significant trouble in C++ mode).  */
+# define option sys_option
 # @INCLUDE_NEXT@ @NEXT_GETOPT_H@
+# undef option
 # undef _GL_SYSTEM_GETOPT
 #endif
 




Reply via email to