In some new code, I want the declaration of functions to clearly
specify whether function arguments and return values can be NULL or not.
Like in Java, where @NonNull and @NonNullable can be attached to a
type. [1]

GCC has a syntax for it, namely:

  extern simple_expression_t
         option_get_value (option_t o)
         ATTRIBUTE_NONNULL ((1));

The problem with it is that it is not intuitive, because
  - the nonnull markers are outside the parameter list,
  - the nullable markers are absent.

Clang supports nearly the desired syntax:

  extern _Nullable simple_expression_t
         option_get_value (_Nonnull option_t o);

Just the _N is a bit clumsy. I therefore use this in config.h,
similar to our treatment of _Noreturn:

#if __clang_major__ >= 4
# define nullable _Nullable
# define nonnull _Nonnull
#else
# define nullable
# define nonnull
#endif

With this, I can nicely write:

  extern nullable simple_expression_t
         option_get_value (nonnull option_t o);

The only problem is a syntax error in xmalloc.c, due to the use of 'nonnull'
for something completely different.

This patch avoids the conflict.

[1] https://blogs.oracle.com/java/post/java-8s-new-type-annotations


2024-02-29  Bruno Haible  <br...@clisp.org>

        xalloc: Don't use identifier 'nonnull'.
        * lib/xmalloc.c (check_nonnull): Renamed from nonnull.

diff --git a/lib/xmalloc.c b/lib/xmalloc.c
index 82e54ef1a5..5befdab77c 100644
--- a/lib/xmalloc.c
+++ b/lib/xmalloc.c
@@ -30,7 +30,7 @@
 #include <string.h>
 
 static void * _GL_ATTRIBUTE_PURE
-nonnull (void *p)
+check_nonnull (void *p)
 {
   if (!p)
     xalloc_die ();
@@ -42,13 +42,13 @@ nonnull (void *p)
 void *
 xmalloc (size_t s)
 {
-  return nonnull (malloc (s));
+  return check_nonnull (malloc (s));
 }
 
 void *
 ximalloc (idx_t s)
 {
-  return nonnull (imalloc (s));
+  return check_nonnull (imalloc (s));
 }
 
 char *
@@ -72,7 +72,7 @@ xrealloc (void *p, size_t s)
 void *
 xirealloc (void *p, idx_t s)
 {
-  return nonnull (irealloc (p, s));
+  return check_nonnull (irealloc (p, s));
 }
 
 /* Change the size of an allocated block of memory P to an array of N
@@ -90,7 +90,7 @@ xreallocarray (void *p, size_t n, size_t s)
 void *
 xireallocarray (void *p, idx_t n, idx_t s)
 {
-  return nonnull (ireallocarray (p, n, s));
+  return check_nonnull (ireallocarray (p, n, s));
 }
 
 /* Allocate an array of N objects, each with S bytes of memory,
@@ -295,13 +295,13 @@ xizalloc (idx_t s)
 void *
 xcalloc (size_t n, size_t s)
 {
-  return nonnull (calloc (n, s));
+  return check_nonnull (calloc (n, s));
 }
 
 void *
 xicalloc (idx_t n, idx_t s)
 {
-  return nonnull (icalloc (n, s));
+  return check_nonnull (icalloc (n, s));
 }
 
 /* Clone an object P of size S, with error checking.  There's no need




Reply via email to