Ask HN: Examples of especially well-written C code?
In light of the recent OpenSSL rant (http://news.ycombinator.com/item?id=1680337): what are some open source projects written in C which are particularly well-written?
I can give one example: I was very pleasantly surprised by the experience of cold-reading the BerkeleyDB source (trying to explain some very odd observed behavior) a few years ago. The code was laid out in a sensible way, such that I could find what I needed reasonably quickly. It was generally clear and straightforward to read, and the few places with "tricky" code were very nicely commented -- including the source of the odd behavior I was hunting for.
Are there other examples of great, readable C code out there?
18 comments
[ 4.9 ms ] story [ 186 ms ] threadGoing further, I'd suggest that most large successful projects in C have clear code that is worthy of study. It's some corollary of the anthropic principle --- if the code wasn't clear, it would never have survived to become successful.
This may only apply to the core of these projects (written by experts) than to the periphery (written by learners). But you might be surprised by how readable the central code is for Apache, Linux, Glibc, Mysql, Perl, Python, etc.
Another problem is that a lot projects "grow" without any vision. Once you understand that, you'll find that most of the successful C projects didn't have much more choice, more because of the history of them than anything else.
However when you have the full control of the platform and have a small numbers of the developers with a good taste (you control the OS and the compiler too) you can maintain "beauty" consistently. In this regard, I suggest you to enjoy Plan 9 sources!
http://plan9.bell-labs.com/wiki/plan9/Sources_repository/ind...
http://github.com/antirez/redis
It's written in an object-oriented style (i.e. structs are "objects", each C file is a "class", and function prototypes are consistent for constuctors/destructors/instance methods). Also, everything is modular in redis (i.e. you can take the redis string or network library and use it in another project without any problems).
I also like the fact that it's portable C (C99 IIRC) that just requires make (no autoconfiguration necessary).
hard tasks are hard to understand
Good programmers can read bad code. I think SSL is likely to be obsficated?
http://www.amazon.com/Interfaces-Implementations-Techniques-...
Beyond that, Tcl/Tk is a large-ish codebase that's still quite manageable, especially considering its age and the many rewrites.
For a more idisyncratic view, I once went through Rob Pike's sam editor. No header guards, sparse comments, short variable and function names. But you could still figure out what's going on without any problems. That was the old portable sam, don't know if the current plan9port one is still that good.
I thought at first that the code samples he was giving were examples of "what not to do", and then was astonished to find him defending them in the text. From page 36, after some horrendous code for Atom_int() page 35:
"When the conversion is done, s points to the desired string, and this string has &str[43] - s characters. str has 43 characters, which is enough to hold the decimal representation of any integer on any conceivable machine. Suppose, for instance, that longs are 128 bits. The string representation of any 128-bit signed integer in octal - base 8 - fits in 128/3 + 1 = 43 characters. The decimal representation can take no more digits than the octal representation, so 43 characters are enough.
The 43 in the definition of str is an example of a 'magic number,' and it's usually better style to define a symbolic name for such values to ensure that the same value is used everywhere. Here, however, the value appears only once, and sizeof is used whenever the value is used. Defining a symbolic name might make the code easier to read, but it will also make the code longer and clutter the name space. In this book, a symbolic name is defined only when the value appears more than once, or when it is part of an interface."
I'm glad to see his priorities presented in such a clear manner. If you feel that your current code is too readable at the expense of "name space clutter", this might be a good book for you. But otherwise, just say no!
ps. In case this example didn't convince you, the following chapter on using setjmp() and longjmp() to roll your own macros for exception handling might be worth glancing at in the online version before you confirm your purchase.
I hope you don't mean that. The bits of original BSD which are still in the FreeBSD tree are pretty ugly -- recent FreeBSD code is much better.