Live data from Hacker News

Generic dynamic array in 60 lines of C

gist.github.com

101–110 of 110 posts

Re: Generic dynamic array in 60 lines of C

#101

Seriously, in this day and age, why are we still stuck with C? There are battle tested container libraries in C++ for e.g.

Yep, once you find yourself writing containers that are found in C++ its time to switch to it. I've seen too many C developers re-write C++ containers in C because they are afraid of C++, its madness.

Indeed, C++ is madness. Unsafe iterators, insane template language compared to cpp

Re: Generic dynamic array in 60 lines of C

#103
post #84
post #13

Not an entirely uncommon idea. I've written one. There's also a well-known one here, in klib: https://github.com/attractivechaos/klib/blob/master/kvec.h

Probably many have written a vector header like this. It baffles me why this one reaches the front page of HN given that the implementation is not that great. A few problems (some have been mentioned by others as well). 1. not using "do {} while (0)". This may lead to compile errors. 2. using uint32_t for capacity. On 64-bit machine, this doesn't save memory. 3. DYN_ARR_RESIZE() may have a quadratic time complexity i…

It’s better that the code isn’t perfect. Reading the code review comments in this thread has been really valuable for me personally. Like, I’m not sure I would’ve learned about the do-while trick had so many people not pointed it out.

Re: Generic dynamic array in 60 lines of C

#104
post #13

Not an entirely uncommon idea. I've written one. There's also a well-known one here, in klib: https://github.com/attractivechaos/klib/blob/master/kvec.h

Who didn't. Almost any C program dealing with strings and collections has to have their own implementation or import one. Part of the reason why C developers "feel" productive, but can't produce anything of meaningful complexity.

>Part of the reason why C developers "feel" productive, but can't produce anything of meaningful complexity.

https://quoteinvestigator.com/2010/05/17/remain-silent/

Re: Generic dynamic array in 60 lines of C

#105
post #99
post #98

The biggest problem with this is that you cannot assign, pass, or return an "instance" of the array struct itself. That's because it's declared as an unnamed struct and in C two unnamed structs are not type compatible even if they have identical fields. C23 did improve struct compatibility [1] but unfortunately not for unnamed structs. [1] https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3003.pdf

You can if you typedef it.

Clever. Seems so obvious in hindsight.

Re: Generic dynamic array in 60 lines of C

#106
Counterpoint to people suggesting size_t for capacity: we recently changed our in-house std::vector replacement from { T* first, last, end; } to { T* first; u32 size, capacity; }.

Not only did this shave 8 bytes off of each instance but in many cases it saved more because they became 16 bytes which reduced alignment padding in other objects that use SIMD types that require 16-byte alignment.

This saved 40 MB of memory for us in https://warframe.fandom.com/wiki/Orb_Vallis which, given the poverty our mobile minspec, was a terrific savings.

Your needs may vary, but it's 2023 we're still cramming 4GB of poop into a 2GB bag.

Re: Generic dynamic array in 60 lines of C

#107

DYN_ARR_RESET should probably be called DYN_ARR_INIT instead, as calling it more than once will leak memory. The handling of endptr in DYN_ARR_RESIZE seems to be incorrect. If I have an array with 2 elements and capacity of 3 and I DYN_ARR_RESIZE it to 5, I now have an array with 5 elements, 3 of which are garbage values.

> The handling of endptr in DYN_ARR_RESIZE seems to be incorrect. If I have an array with 2 elements and capacity of 3 and I DYN_ARR_RESIZE it to 5, I now have an array with 5 elements, 3 of which are garbage values. Why do you say this is wrong? That's exactly what I would expect.

> Why do you say this is wrong?

Exposing uninitialized memory as valid values tends to be a really bad idea.

Re: Generic dynamic array in 60 lines of C

#109

Counterpoint to people suggesting size_t for capacity: we recently changed our in-house std::vector replacement from { T* first, last, end; } to { T* first; u32 size, capacity; }. Not only did this shave 8 bytes off of each instance but in many cases it saved more because they became 16 bytes which reduced alignment padding in other objects that use SIMD types that require 16-byte alignment. This saved 40 MB of memor…

In game development, you'll want to do things like this often, but general purpose programming shouldn't adopt this practice. It's literally what the type is for.
Post reply on HN