4 ms·
I’m actually implementing that right now for my own use, as a pre-processor. There is a much more advanced design and implementation at “A defer mechanism for
by AlbertoGP 5y ago
I’m actually implementing that right now for my own use, as a pre-processor.
There is a much more advanced design and implementation at “A defer mechanism for C” (December 2020): https://gustedt.wordpress.com/2020/12/14/a-defer-mechanism-for-c/ https://gustedt.wordpress.com/2020/12/14/a-defer-mechanism-f...
For my own purposes, I think I can live without handling stack unwinding so I continue working on my pre-processor.
Since the pre-processor is not yet finished, there I use a vector¹ of {.pointer, .destructor} where I put objects after initialization, with one macro at the end of each managed scope that calls the destructors for that scope in reverse order, then another macro meant for the function exit points that calls all the destructors in that vector. This has been built many times before by other people of course, it’s just an exercise to see which difficulties arise.
¹ Vector, growable array: I did my own trivial type-generic growable array, with the classic {.capacity, .len, .items}, but again there are many previous implementations. The two I’ve found more interesting are:
- “C Template Library (CTL)”: https://github.com/glouw/ctl https://github.com/glouw/ctl
- “Klib: a Generic Library in C”: https://github.com/attractivechaos/klib/ https://github.com/attractivechaos/klib/
- glouwbug 5y agoWith a bit of trickery CTL works much like the STL, in that containers can be built of containers: #define P #define T int #include <vec.h> #define T vec_int #include <deq.h> A deq_vec_int - analogous to std::deque<std::vector<int>> - is a neat example.
- cygx 5y agoThere's also a CTL fork that might be of interest: https://github.com/rurban/ctl https://github.com/rurban/ctl
- tirrex 5y agoFor a vector alternative, I find this one easy to read and use : https://github.com/tezc/sc/tree/master/array https://github.com/tezc/sc/tree/master/array It is just an array of your type, e.g int *numbers, so you have type info in debugger as well.
- Arch-TK 5y agoNo type safety and broken alignment. No thanks.
- tirrex 5y agoIsn’t it type safe? e.g you can’t add char* to a double array. What do you mean by broken alignment?
- Arch-TK 5y agoIt lacks type safety because it's not possible to distinguish between an sc_array and a pointer so there's no way of detecting that someone passed a char * that nobody had ever called sc_array_create on to sc_array_add for example. The alignment is broken because nothing in the C standard guarantees that the elems member of sc_array will be aligned correctly for any possible element type. I also spotted another problem, in sc_array_init the code `void *p = a` is also not guaranteed to work. In an example snippet such as `int iv; sc_array_create(iv, 0);` expands to `sc_array_init(&iv, sizeof iv, 0)` so the type of the expression `&iv` is `int *` which is then being converted to `void *` in the function which is actually not allowed by the standard. This is also the reason why if you were writing a wrapper around realloc which exited if the allocation failed you would still have to pass in the current pointer with void * and return the new pointer with void *. This could be applied here actually as an easy fix but it indicates even further to me that the author of the library is taking a very leisurely approach to writing conforming C. This pattern also appears in the other two functions though and I'm not sure if in those cases it's something which can be easily fixed.