Git development
 help / color / mirror / Atom feed
* [PATCH 1/2] add COPY_ARRAY
@ 2016-09-25  7:15 René Scharfe
  2016-09-25  7:24 ` [PATCH 6/7] use COPY_ARRAY René Scharfe
  2016-09-25  7:41 ` [PATCH 1/2] add COPY_ARRAY Jeff King
  0 siblings, 2 replies; 5+ messages in thread
From: René Scharfe @ 2016-09-25  7:15 UTC (permalink / raw)
  To: Git List; +Cc: Junio C Hamano, Jeff King

Add COPY_ARRAY, a safe and convenient helper for copying arrays,
complementing ALLOC_ARRAY and REALLOC_ARRAY.  Users just specify source,
destination and the number of elements; the size of an element is
inferred automatically.

It checks if the multiplication of size and element count overflows.
The inferred size is passed first to st_mult, which allows the division
there to be done at compilation time.

As a basic type safety check it makes sure the sizes of source and
destination elements are the same.  That's evaluated at compilation time
as well.

COPY_ARRAY is safe to use with NULL as source pointer iff 0 elements are
to be copied.  That convention is used in some cases for initializing
arrays.  Raw memcpy(3) does not support it -- compilers are allowed to
assume that only valid pointers are passed to it and can optimize away
NULL checks after such a call.

Signed-off-by: Rene Scharfe <l.s.r@web.de>
---
 git-compat-util.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/git-compat-util.h b/git-compat-util.h
index 37cce07..91775ce 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -801,6 +801,14 @@ extern FILE *fopen_for_writing(const char *path);
 #define ALLOC_ARRAY(x, alloc) (x) = xmalloc(st_mult(sizeof(*(x)), (alloc)))
 #define REALLOC_ARRAY(x, alloc) (x) = xrealloc((x), st_mult(sizeof(*(x)), (alloc)))
 
+#define COPY_ARRAY(dst, src, n) copy_array((dst), (src), (n), sizeof(*(dst)) + \
+	BUILD_ASSERT_OR_ZERO(sizeof(*(dst)) == sizeof(*(src))))
+static inline void copy_array(void *dst, const void *src, size_t n, size_t size)
+{
+	if (n)
+		memcpy(dst, src, st_mult(size, n));
+}
+
 /*
  * These functions help you allocate structs with flex arrays, and copy
  * the data directly into the array. For example, if you had:
-- 
2.10.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2016-09-25  8:58 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-09-25  7:15 [PATCH 1/2] add COPY_ARRAY René Scharfe
2016-09-25  7:24 ` [PATCH 6/7] use COPY_ARRAY René Scharfe
2016-09-25  7:26   ` René Scharfe
2016-09-25  7:41 ` [PATCH 1/2] add COPY_ARRAY Jeff King
2016-09-25  8:58   ` René Scharfe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox