In the last few years, I haven't had cause to write much C code; just enough to stop me getting rusty. I remain very fond of the C programming language, and sometimes I find myself thinking that programming in C has its advantages, despite the need to pay attention to a few details that are not an issue in higher-level languages. Maybe C is not so bad. Maybe, if I had to tackle a project with the right set of requirements, I'd work in C again.
But coming into contact with C code can be like reading about surgery before anaesthetic: The unwelcome and painful realization that people had to live like that for so long, and that in some primitive parts of the world, they still do.
Although I don't get to write much C code, I do still regularly refer to C code written by others. But there's a depth of understanding of a language and its milieu that can only be gained by writing a significant amount of code in that language, or making significant changes to an existing project. Today, I've been doing the latter.
The project in question is a relatively successful open source project, of a non-trivial size (150k lines). The leaders and main contributors appear to be competent and experienced, and have made sensible design decisions. After a superficial review of the code, my response was quite positive. It adheres to a range of uncontroversial coding standards. It is consistently formatted. And it uses utility functions where appropriate to handle error prone tasks safely. In particular, it avoids the direct use of malloc and friends, and instead uses a set of helper macros and functions for allocation and deallocations of common data structures and arrays.
But after a few hours of working on this codebase, I began to realize that it is riddled with allocation and deallocation bugs. The helpers help, but not enough. The consequence of the smallest confusion over the ownership of some data structure is a memory leak.
I'm not going to name the project, because I continue to believe that its overall quality is very good, and that the developers have tried hard to get these issues right. What it brings home to me is a fact that I haven't been forced to face for a long time: while bad programmers can write bad code in any language, even good programmers find it hard to write good, bug-free code in C.