Much feedback on the recent Array List C implementation applies here too.
()
around macro parameters
Good practice to enclose a macro parameters with ()
, yet a
still remain problematic. Example:
// #define array_push(a, elem) do { a = array_push_impl(a, elem); } while(0)
#define array_push(a, elem) do { a = array_push_impl((a), (elem)); } while(0)
Check allocation success
void *a = malloc(sizeof(Array_Header));
if (a == NULL) return NULL; // add
.h file: only code necessary #include
for the headers.
#include <assert.h>
and perhaps others not needed in the .h file. Remove them.
Unnecessary struct
typedef struct { ... } Array_Header;
not needed in the .h file. Move to the .c file.
Even better, re-define functions to use a pointer to Array_Header
.
Array alignment
As OP wants to use header + 1
as the start of an array of any type, additional padding may be needed in Array_Header
. To Since *alloc()
returns a pointer good for all alignments, to make certain header + 1
is also aligned for any type use a FAM of type max_align_t
(which is an object type whose alignment is the greatest fundamental alignment).
typedef struct {
void (*freeElem)(void *);
size_t szElem;
size_t ctElem;
size_t cpElem;
max_align_t a[]; // Add
} Array_Header;