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