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

Reply via email to