4 ms·
I'm sorry, I don't completely understand what your point. You seem to be alluding to "what C is actually good for", but it's not clear to me what that's suppose
by sfpotter 4y ago
I'm sorry, I don't completely understand what your point. You seem to be alluding to "what C is actually good for", but it's not clear to me what that's supposed to be. I understand that you think C should not be used to develop generic components that are reused, and that data structures and such should be re-rolled or copy-pasted each time they're used.
On the other hand, you do hint that you think C can be used reusably, provided that the ABI is the focus. I agree with this.
In my opinion, the techniques discussed in the book are in fact useful techniques for accomplishing exactly this end. If you want reusability the ABI way, what you want is a small surface area which changes extremely slowly. Ideally, you want each ABI to be a subset of the last to avoid breaking changes. OK: accomplishing data hiding via opaque pointers in tandem with a simple, high-level interface is one way to accomplish this, and is the main lesson to be learned by reading this book. (I would argue you really only need to read a chapter or two to learn it, but that's a different story---I would argue that this book is in fact not very good for this reason, but whatever.)
If you look at most reusable C libraries, they take this approach. Obvious this book takes a bit of an extreme approach where as much of the details of a data type are hidden as possible, but there is no real reason to do this provided that the details of a type are stable. Then it's OK to expose them as part of the interface.
I suppose I take your point that in reading this book, one might get the idea that it's a good idea to develop an STL-style library to use with C and run with that. On the other hand, someone who is learning C might just as well read many books about it (or read lots of code), and be able to contextualize this book well enough to understand that it should be taken with a grain of salt.
I think it's also important to point out that there are exceptions to these "rules". GLib is a generic STL-style library written in C which seems to be pretty widely used. At the other end of the spectrum, you have more people (I think mostly in the games community) developing "header only C libraries". YMMV.
- chubot 4y agoThis comment sums it up best: https://news.ycombinator.com/item?id=33142349 https://news.ycombinator.com/item?id=33142349 So basically, use EITHER idiomatic C, which means long functions / few internal interfaces, reuse with ABIs not APIs, bespoke data structures, etc. OR use C++ and ADTs (type safety, abstraction, polymorphism). Or use Rust if you don't need compatibility. So books like CII are of very limited use, especially not for beginners. They will be fighting with the language and not understanding what it's about. ---- To sum it up, C is better for coarse-grained reuse (deep interfaces a la Ousterhout, Unix file system) than fine-grained reuse like CII (hash table, array, set) Related long article I wrote about API (compile time) vs. ABI (protocol, runtime) and related issues: https://www.oilshell.org/blog/2022/03/backlog-arch.html https://www.oilshell.org/blog/2022/03/backlog-arch.html ---- I'll take your point that if you want ABI stability, then hiding layout behind a pointer and not exposing structs is a good idea! Although that pointer's type doesn't necessarily have to be void* as it is in CII -- it could just be an application-specific type Also agree that there are several different ways of using C and C++.
- sfpotter 4y agoWhy is "idiomatic C" equivalent to "long functions and few internal interfaces"? The whole point of having a small surface-area for your ABI with plenty of detail hiding is that you are free to do what you like beneath it. If the code uses a struct named "hash_map" that takes a generic hash function and stores void pointers, but runs fast for my purposes, what do I care? These techniques give you a controlled way to build black boxes. C is a very flexible language, and it is possible to build up quite a variety of patterns in it. Your job as an engineer is to look in your toolbox and select the best tool for the job. Adhering to a "correct idiom" gets in the way of this.