4 ms·
C macros-faking-generics really aren't that bad (your "unsigned char" case is really easy to solve - use another macro). It's a bit goofy having different types
by lacampbell 10y ago
C macros-faking-generics really aren't that bad (your "unsigned char" case is really easy to solve - use another macro). It's a bit goofy having different types floating around like "array_of_int", "array_of_float", but you can create them in a single line when needed, and once you create them, they work, and efficiently.
They're not an ideal solution by any stretch, but it's not the nightmare scenario you envision wrt generic data structures in C.
- dbaupp 10y agoI would be interested in the specifics of the spaces thing (knowing more about ones tools is good) but "10 minutes" to handle all the various issues and bugs that will inevitably pop up from wrangling macros?
- lacampbell 10y agoYeah 10 minutes is quite a bit off, at least for me. The various issues and bugs that arose all came about when developing the data structures themselves - they didn't crop up in actual usage. Though my approach was to use a separate header and source file for each new data type I parameterised them by. So I had an "int_array.c" and an "int_array.h". And inside the header would just be function declarations generated by the macro. I basically didn't like the idea of dumping in a whole implementation of a data structure and all its operations with a macro every single time I wanted to use it. YMMV but I found it worked well.
- dbaupp 10y agoThat approach of a single invocation was what I would personally assume would be done (or put it in the header that defines the data type, for a custom one), but I'm not sure how that solves spaces?
- civility 10y agoNo more spaces: typedef unsigned char uchar; DECLARE_AND_IMPLEMENT_ARRAY_API(uchar)
- PeCaN 10y agoI actually did this¹⋅² some time ago. Since then I've moved on from a hardcore C developer to C++ and Ada³, but it wasn't necessarily a bad solution. I think given how little C gives you to work with, it's the best solution you can do. It does make debugging a chore. I ended up with a Makefile rule to run the test suite through the preprocessor (and did some hackery to exclude #include of system headers), format it with clang-format, and build that. Not exactly pretty or easy, but it got the job done. 1. https://github.com/alpha123/yu/blob/master/src/yu_splaytree.h https://github.com/alpha123/yu/blob/master/src/yu_splaytree.... 2. https://github.com/alpha123/yu/blob/master/test/test_splaytree.c https://github.com/alpha123/yu/blob/master/test/test_splaytr... 3. Where this sort of thing is much easier and I am happier and more productive.
- lomnakkus 10y agoHaving worked in a code base like this (prior to migration to C++11), I'd agree that they're not necessarily a "nightmare", but they lead to code that's so verbose that it tends to really obscure the actual logic of a piece of code. (Especially anything more complicated than a simple array, e.g. associative maps or multi-dimensional arrays, and iteration constructs can be hellish.)