bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: module c-nullptr: error compiling groff


From: Bruno Haible
Subject: Re: module c-nullptr: error compiling groff
Date: Mon, 06 Feb 2023 04:27:18 +0100

Bjarni Ingi Gislason wrote:
> Debian testing (bookworm/sid)
> 
> gcc (Debian 12.2.0-14) 12.2.0
> 
> GNU Make 4.4.0.90
> 
> 
> [...]
>   CXX      src/roff/troff/env.o
> In file included from /usr/include/c++/12/bits/stl_bvector.h:61,
>                  from /usr/include/c++/12/vector:65,
>                  from ../src/roff/troff/charinfo.h:20,
>                  from ../src/roff/troff/env.cpp:31:
> /usr/include/c++/12/bits/functional_hash.h:273:12: error: redefinition of 
> 'struct std::hash<long int>'
>   273 |     struct hash<nullptr_t> : public __hash_base<size_t, nullptr_t>
>       |            ^~~~~~~~~~~~~~~
> /usr/include/c++/12/bits/functional_hash.h:157:3: note: previous definition 
> of 'struct std::hash<long int>'
>   157 |   _Cxx_hashtable_define_trivial_hash(long)
>       |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> make[1]: *** [Makefile:10126: src/roff/troff/env.o] Error 1

Thanks for the report.

I reproduce it with the just-added unit tests, with GCC 11 or 12, but not
with other compilers (GCC 10 or older, clang, MSVC, AIX xlc, Solaris cc).

But even when there is no error in the unit test, there could be errors
in application code, if we define nullptr to some value that is inferior
to what the C++ compiler already does. So, the guideline should be: If the
C++ compiler already supports 'nullptr', leave it alone and don't define
it as a macro.

I found out that for g++ and clang++, 'nullptr' is supported with the
options -std=c++11, -std=c++14, -std=c++17 and not supported with the
option -std=c++03. To detect this situation, the value of __cplusplus
can be used. The various __cpp_* macros don't help here.

Also, MSVC 14 supports it, although its __cplusplus value is only
199711L.

In my tests, AIX xlc and Solaris cc (up to Developer Studio 12.6)
don't support it.

Taken together, this gives this fix.


2023-02-05  Bruno Haible  <bruno@clisp.org>

        c-nullptr: Fix conflict with libstdc++ in GCC >= 11.
        Reported by Bjarni Ingi Gislason <bjarniig@simnet.is> in
        <https://lists.gnu.org/archive/html/bug-gnulib/2023-02/msg00030.html>.
        * m4/c-nullptr.m4 (gl_C_NULLPTR): Don't define nullptr if it is already
        defined. In C++ mode, ignore the result of the configure test and don't
        define it when we know that the C++ compiler already supports it.

diff --git a/m4/c-nullptr.m4 b/m4/c-nullptr.m4
index af79854696..960eeff18d 100644
--- a/m4/c-nullptr.m4
+++ b/m4/c-nullptr.m4
@@ -18,13 +18,25 @@ AC_DEFUN([gl_C_NULLPTR],
 ])
 
   AH_VERBATIM([nullptr],
-[#ifndef HAVE_C_NULLPTR
-# ifndef __cplusplus
-#  define nullptr ((void *) 0)
-# elif 3 <= __GNUG__
-#  define nullptr __null
+[#ifndef nullptr /* keep config.h idempotent */
+# ifdef __cplusplus
+/* For the C++ compiler the result of the configure test is irrelevant.
+   We know that at least g++ and clang with option -std=c++11 or higher, as 
well
+   as MSVC 14 or newer, already have nullptr.  */
+#  if !(((defined __GNUC__ || defined __clang__) && __cplusplus >= 201103L) \
+        || (defined _MSC_VER && 1900 <= _MSC_VER))
+/* Define nullptr as a macro, the best we can.  */
+#   if 3 <= __GNUG__
+#    define nullptr __null
+#   else
+#    define nullptr 0L
+#   endif
+#  endif
 # else
-#  define nullptr 0L
+/* For the C compiler, use the result of the configure test.  */
+#  ifndef HAVE_C_NULLPTR
+#   define nullptr ((void *) 0)
+#  endif
 # endif
 #endif])
 ])








reply via email to

[Prev in Thread] Current Thread [Next in Thread]