top | item 5786308

Ask HN: Tips for maintaining a C codebase?

25 points| shortlived | 12 years ago

My team has a small but growing C library. We have a set of coding and naming conventions that are generally followed and things are fairly modular. Most of us are not C programmers though, so I want to continue reading and learning from other code to bring in useful ideas to our code base. Thanks in advance.

16 comments

order
[+] tptacek|12 years ago|reply
Wrap your libraries up in ADT-style interfaces.

Give every such interface a _create() and a _destroy() method.

Have _destroy() either return a pointer (which will always be NULL), or (better, I think) take a pointer-to-pointer so that it can zero the pointer out after destroying the object.

Don't check malloc; instead, rig your code up to detonate if malloc ever fails. Checked allocations create rats nests of error handling.

Have a common hash table, a common binary tree, and a common list or resizable array, working on void-star. Don't allow programmers do implement their own hash table or tree.

Have a common logging library, with debug levels.

[+] euroclydon|12 years ago|reply
Thomas, You've mentioned that your new-programming-language-exercise du jour is to write a virtual machine (or microcontroller emulator), right? I'd like to try that in C. How would you go about writing this in a simple way. I know I could google this, but I'm worried I'll find results with too many details and pollute my discovery process.

Really, I'd just like some opinionated answers to the following from anyone who cares:

1) What is a simple instruction set that I can support?

2) What existing programs are available for that instructions set, or what set of tools are there to compile to that instructions set?

3) What are the high level tasks that I will need to accomplish to write this virtual machine?

4) What should I look up or borrow exclusively versus figure out for myself?

Thanks!

[+] swah|12 years ago|reply
Normally you also recommend David Hanson's "C Interfaces and Imlpementations" which is a really great read.
[+] shortlived|12 years ago|reply
We are not so good with sticking to ADT-style interfaces but we need to be. And the malloc check is great point. We've definitely gone down that road and it is hell.
[+] greaterscope|12 years ago|reply
Two projects you may want to review for ideas are Redis and toybox.

Redis comes to mind because it started out as largely a single file of code that has since been split and organized into multiple files. The code is quite approachable; you'll likely understand how most of it works after a day of causal browsing. http://redis.io

Toybox comes to mind because it's insanely modular, and aggressive about code re-use. The logic can feel a bit dense at times, but he's going for size and speed. I'm a big fan of Rob's efforts. http://landley.net/code/toybox/

[+] shortlived|12 years ago|reply
>> redis

Thanks for this pointer. We also tend to be more organic in modularity. Start with a big chunk of code and split it when the time is right.

>> Toyboy, "insanely modular"

I haven't read the toybox code (so maybe it's not that bad) but we've had some folks go to extreme in the modularity/code-reuse direction. Their code is NOT easy to read.

[+] shortlived|12 years ago|reply
On the subject of code reading: are there specific areas of the linux kernel (or minux or ...) that someone would recommend to read?
[+] dllthomas|12 years ago|reply
If you've a bunch of bare integers or floats you're passing around with meaning beyond "number" and you're tempted to wrap them in a typedef to add some readability, consider wrapping in a struct with no additional elements. The compiler will boil it away entirely when it comes time to generate code, but it'll catch it when you mix up the order of arguments to a function and the like.