Hello, I've been coding a 100% macro-based dynamic array that is meant to be like a
std::vector for C.
C++ users should find it very familiar, here's a basic usage example:
dynarray(int) dai;
dynarray_create(dai, 5);
dynarray_pushback(dai, 10);
dynarray_pushback(dai, 20);
dynarray_pushback(dai, 30);
for (const int *pi = dynarray_begin(dai); pi != dynarray_end(dai); ++pi)
printf("%d ", *pi); // should print "10 20 30 "
printf("\n");
printf("%zu\n", dynarray_count(dai)); // should print "3"
dynarray_destroy(dai);
Naturally I am very interested in fixing bugs if they are found! Writing everything as macros is tricky but I want to be sure that memory leaks haven't been introduced.
Also, the attached source builds with a warning, which I would like to fix:
dynarray_test\dynarray_test.c(4): warning #2154: Unreachable code.Edits:
- Fixed dynarray_pushfront().
- Simplified dynarray_create() and made small changes.
- Fixed dynarray_pushfront() and dynarray_pushback() to update capacity.
- Fixed dynarray_reserve() and dynarray_resize() to prevent potential memory leak; now they can fail without damage but without error code, just like std::vector::reserve() and std::vector::resize().
- Fixed dynarray_reserve() to update data pointer.
- Minor style update.
- Implemented dynarray_insert().
- Implemented dynarray_search().
- Major interface changes, and style adjustments.
Nice. :)
Right now I'm thinking to change the interface such that the macros will accept non-pointers. For instance:
// currently
dynarray_pushback(&dai, 0);
dynarray_pushback(&dai, 1);
dynarray_pushback(&dai, 2);
// after change
dynarray_pushback(dai, 0);
dynarray_pushback(dai, 1);
dynarray_pushback(dai, 2);
Doing the above would clean up code a little but I'm not sure if it's the right thing to do. Then again the macros are currently pretending to be functions when they're not, so that's probably not right either.
Any thoughts?
Maybe this my old code could be of any help ;)
Thanks for sharing. I see you went in the direction of using macros to declare functions whereas in my case macros are the functions. I think I'll stay on this road just to see how bad things get when I implement more complicated data structures.
Yes I used generic functions and macros to enforce typechecking. I made this decision because using this code as a replacement in C++ modules, that I was porting to C, I need type checking to avoid errors (it was large code).
But it is just a way :), you can use what you think it's better for you ;)