On 4/21/21 17:18, Bruno Haible wrote:
xnmalloc and XNMALLOC take 2 arguments, whereas xreallocarray takes 3
arguments. It is often possible to express a function with a simple
interface as a special case of a more complex function. If, in many
use-cases, the simpler function is sufficient, users should not be
forced to understand the more complex function.
Good point. Also, xnmalloc enables better static checking, as it has
__attribute__ ((__malloc__)), __attribute__ ((__malloc__ (free, 1))),
and __attribute__ ((__returns_nonnull__)), whereas xreallocarray
doesn't have these.
I noticed this when converting GNU diffutils to use ximalloc etc, and
this this convinced me to add xinmalloc, by installing the attached
patch. I plan to use this in GNU diffutils and probably other apps.
Should we change xreallocarray to always return nonnull? We could then
add __attribute__ ((__returns_nonnull__)) to its declaration. This might
help performance and/or static checking a bit. The only downside I can
see is that xreallocarray's semantics would differ a bit more from glibc
reallocarray's.From de6894e291369f73dc343d544b29367493b312b4 Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Tue, 19 Oct 2021 16:31:32 -0700
Subject: [PATCH] xalloc: new function xinmalloc
* lib/xmalloc.c (xinmalloc): New function, which is like
xnmalloc but for idx_t instead of size_t.
---
ChangeLog | 6 ++++++
lib/xalloc.h | 3 +++
lib/xmalloc.c | 6 ++++++
3 files changed, 15 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index a017453dc..2f19e30a2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2021-10-19 Paul Eggert <egg...@cs.ucla.edu>
+
+ xalloc: new function xinmalloc
+ * lib/xmalloc.c (xinmalloc): New function, which is like
+ xnmalloc but for idx_t instead of size_t.
+
2021-10-18 Paul Eggert <egg...@cs.ucla.edu>
regex: fix buffer read overrrun
diff --git a/lib/xalloc.h b/lib/xalloc.h
index ee07113fe..7f2c3fb8a 100644
--- a/lib/xalloc.h
+++ b/lib/xalloc.h
@@ -60,6 +60,9 @@ void *xmalloc (size_t s)
void *ximalloc (idx_t s)
_GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE
_GL_ATTRIBUTE_ALLOC_SIZE ((1)) _GL_ATTRIBUTE_RETURNS_NONNULL;
+void *xinmalloc (idx_t n, idx_t s)
+ _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE
+ _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2)) _GL_ATTRIBUTE_RETURNS_NONNULL;
void *xzalloc (size_t s)
_GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE
_GL_ATTRIBUTE_ALLOC_SIZE ((1)) _GL_ATTRIBUTE_RETURNS_NONNULL;
diff --git a/lib/xmalloc.c b/lib/xmalloc.c
index 51a0832de..d5def0bc7 100644
--- a/lib/xmalloc.c
+++ b/lib/xmalloc.c
@@ -101,6 +101,12 @@ xnmalloc (size_t n, size_t s)
return xreallocarray (NULL, n, s);
}
+void *
+xinmalloc (idx_t n, idx_t s)
+{
+ return xireallocarray (NULL, n, s);
+}
+
/* If P is null, allocate a block of at least *PS bytes; otherwise,
reallocate P so that it contains more than *PS bytes. *PS must be
nonzero unless P is null. Set *PS to the new block's size, and
--
2.31.1