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 <[email protected]>
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