To support an approximation to C23's nullptr keyword I installed the attached patch into Gnulib. To test it a bit I'm using the new c-nullptr module in GNU diffutils, by preferring nullptr to NULL in the diffutils source. See:

https://git.savannah.gnu.org/cgit/diffutils.git/commit/?id=09f8e2b0a92f3d25325f5b1df20384140261ee10

Assuming this works out, at some point I would like to change Gnulib itself to prefer nullptr to NULL, due to nullptr's somewhat-better properties. There's no rush of course.

With current c-nullptr Gnulib .h files would continue to use NULL rather than nullptr, since we couldn't assume client code includes a <config.h> that defines nullptr on pre-C23 platforms, so perhaps at some point that could be improved as well.
From 28c79f93121923acb8cc77270a63701ed4926846 Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Sun, 5 Feb 2023 09:47:12 -0800
Subject: [PATCH] c-nullptr: new module

* doc/gnulib.texi (nullptr): New section.
* doc/posix-headers/stddef.texi: Document lack of nullptr_t.
* m4/c-nullptr.m4, modules/c-nullptr: New files.
---
 ChangeLog                     |  7 ++++++
 doc/gnulib.texi               | 42 +++++++++++++++++++++++++++++++++++
 doc/posix-headers/stddef.texi |  6 +++++
 m4/c-nullptr.m4               | 30 +++++++++++++++++++++++++
 modules/c-nullptr             | 20 +++++++++++++++++
 5 files changed, 105 insertions(+)
 create mode 100644 m4/c-nullptr.m4
 create mode 100644 modules/c-nullptr

diff --git a/ChangeLog b/ChangeLog
index 3cc97a8c34..51a731f115 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2023-02-05  Paul Eggert  <egg...@cs.ucla.edu>
+
+	c-nullptr: new module
+	* doc/gnulib.texi (nullptr): New section.
+	* doc/posix-headers/stddef.texi: Document lack of nullptr_t.
+	* m4/c-nullptr.m4, modules/c-nullptr: New files.
+
 2023-02-05  Bruno Haible  <br...@clisp.org>
 
 	Update build-aux/po/Makefile.in.in.
diff --git a/doc/gnulib.texi b/doc/gnulib.texi
index e9a4ace67f..b3f011818c 100644
--- a/doc/gnulib.texi
+++ b/doc/gnulib.texi
@@ -867,6 +867,7 @@ substituted by Gnulib.
 @menu
 * alignof::        @code{alignas} and @code{alignof}
 * bool::           @code{bool}, @code{false}, and @code{true}
+* nullptr::        @code{nullptr}
 * static_assert::  @code{static_assert}
 @end menu
 
@@ -916,6 +917,47 @@ On pre-C23 platforms, the keyword substitutes are macros.
 On pre-C23 platforms, the keyword substitutes assume C99 or later.
 @end itemize
 
+@node nullptr
+@section @code{nullptr}
+
+Gnulib module: c-nullptr
+
+@cindex null pointer
+The @code{c-nullptr} module arranges for @code{nullptr} to act
+like standard C@.
+
+The C @code{nullptr} keyword yields a null pointer.  It differs from
+the @code{NULL} macro, in that @code{NULL} might be an integer whereas
+@code{nullptr} is of a special @code{nullptr_t} type with only one
+value, namely @code{nullptr} itself.  Using @code{nullptr} can help
+some compilers emit more sensible warnings, can avoid the need to cast
+a null pointer passed to a function prototyped with an ellipsis, and
+removes the need to include @code{<stddef.h>} merely to define
+@code{NULL}.
+
+Portability problems fixed by Gnulib:
+@itemize
+@item
+Some platforms lack @code{nullptr}:
+GCC 12, Clang 15, and other pre-2023 C compilers.
+@end itemize
+
+Portability problems not fixed by Gnulib:
+@itemize
+@item
+On older platforms, @code{nullptr} is a macro instead of a keyword.
+
+@item
+On older platforms, @code{nullptr} does not have the type @code{nullptr_t}.
+In C, it has type @code{void *}; in C++ it has an integer type.
+
+@item
+On older platforms Gnulib cannot easily emulate @code{nullptr_t}, so
+null pointer type checking is more error prone, and @code{_Generic}
+expressions cannot reliably distinguish @code{nullptr}'s type from
+integer or @code{void *} types.
+@end itemize
+
 @node static_assert
 @section @code{static_assert}
 
diff --git a/doc/posix-headers/stddef.texi b/doc/posix-headers/stddef.texi
index fe7ed26c9b..e240f93363 100644
--- a/doc/posix-headers/stddef.texi
+++ b/doc/posix-headers/stddef.texi
@@ -35,6 +35,12 @@ it does not fulfil the expectations of other system header files.
 
 Portability problems not fixed by Gnulib:
 @itemize
+@item
+@cindex null pointer type
+Some platforms fail to provide @code{nullptr_t},
+which Gnulib cannot usefully emulate:
+GCC 12, Clang 15, and other pre-2023 C compilers.
+
 @item
 Some platforms provide an @code{offsetof} macro that cannot be used in
 arbitrary expressions:
diff --git a/m4/c-nullptr.m4 b/m4/c-nullptr.m4
new file mode 100644
index 0000000000..af79854696
--- /dev/null
+++ b/m4/c-nullptr.m4
@@ -0,0 +1,30 @@
+# Check for nullptr that conforms to C23.
+
+dnl Copyright 2023 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_C_NULLPTR],
+[
+  AC_CACHE_CHECK([for nullptr], [gl_cv_c_nullptr],
+    [AC_COMPILE_IFELSE(
+       [AC_LANG_SOURCE([[int *p = nullptr;]])],
+       [gl_cv_c_nullptr=yes],
+       [gl_cv_c_nullptr=no])])
+  if test "$gl_cv_c_nullptr" = yes; then
+    AC_DEFINE([HAVE_C_NULLPTR], [1], [Define to 1 if nullptr works.])
+  fi
+])
+
+  AH_VERBATIM([nullptr],
+[#ifndef HAVE_C_NULLPTR
+# ifndef __cplusplus
+#  define nullptr ((void *) 0)
+# elif 3 <= __GNUG__
+#  define nullptr __null
+# else
+#  define nullptr 0L
+# endif
+#endif])
+])
diff --git a/modules/c-nullptr b/modules/c-nullptr
new file mode 100644
index 0000000000..bc5fa43200
--- /dev/null
+++ b/modules/c-nullptr
@@ -0,0 +1,20 @@
+Description:
+A nullptr that is like C23.
+
+Files:
+m4/c-nullptr.m4
+
+Depends-on:
+
+configure.ac:
+gl_C_NULLPTR
+
+Makefile.am:
+
+Include:
+
+License:
+LGPLv2+
+
+Maintainer:
+all
-- 
2.37.2

Reply via email to