Skip to content

Commit 60566cb

Browse files
rscharfegitster
authored andcommitted
add COPY_ARRAY
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent a63d31b commit 60566cb

File tree

1 file changed

+8
-0
lines changed

1 file changed

+8
-0
lines changed

git-compat-util.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -785,6 +785,14 @@ extern FILE *fopen_for_writing(const char *path);
785785
#define ALLOC_ARRAY(x, alloc) (x) = xmalloc(st_mult(sizeof(*(x)), (alloc)))
786786
#define REALLOC_ARRAY(x, alloc) (x) = xrealloc((x), st_mult(sizeof(*(x)), (alloc)))
787787

788+
#define COPY_ARRAY(dst, src, n) copy_array((dst), (src), (n), sizeof(*(dst)) + \
789+
BUILD_ASSERT_OR_ZERO(sizeof(*(dst)) == sizeof(*(src))))
790+
static inline void copy_array(void *dst, const void *src, size_t n, size_t size)
791+
{
792+
if (n)
793+
memcpy(dst, src, st_mult(size, n));
794+
}
795+
788796
/*
789797
* These functions help you allocate structs with flex arrays, and copy
790798
* the data directly into the array. For example, if you had:

0 commit comments

Comments
 (0)