Back to the Basic with ANSI C


I am going through the classic The C Programming Language by Dennis Ritchie and Brian Kernighan. It is less than 300 pages long, surprisingly concise and easy to follow.

Over this past year, I have read some interesting articles such as the arena allocator by Ryan Fleury, and bits and pieces from @tsoding and other veteran developers. An idea naturally grew that I should look at C as a standalone language, free from the legacy of C++, which has been claimed to supercede C, because “more features” == “better”, right? Right? [insert Anakin-Padme meme here]

Well, back in college I came into contact with C++ first and developed this idea that C++ supercedes C, because I thought more features means better.

That was silly.

I learned the hard way that this is not true. The two languages indeed share a great deal of syntatic coating, and C can interop with C++ most of the time. However, the places where they differ are significant. The two can be orthogonal in some categories of applications. These are advanced topics that have been mostly invisible to the eyes of the newbie me.

Sometimes, things have to be learned the hard way.

So what was the problem?

The problem was misaligned expectations.

I got a reality check when reaching the course in Systems Programming and working on a Linux file-system project. My Systems professor — who recently retired after having taught for 55 years (!) — operated on a different time scale, using coding paradigm, patterns and system specs from a different point in time.

The pre-requisite courses didn’t prepare me enough to handle such an ancient being. I came in with little understanding of the hardware abstraction. To compound the problem, because I learned C++ first, I carried baggages such as object-oriented programming, template programming etc. These things are mostly unnecessary when programming at the kernel level. They actually interfered with the learning process. At this layer of abstraction, everything is about memory allocation and signal handling, for which, the hardware specs and OS interface must be considered.

More specifically, I encountered the problem of memory alignment. I ran into this problem when trying to map data on disk to the file-system struct defined in the project’s headers. The project itself is an EXT2 system for a presumed 32-bit architecture.

Modern hardware have moved on from 32-bit to 64-bit. Many kernel struct were expanded to accomodate more information about the system. Many default specs also changed subtly. Ultimately, the mismatch in specs and memory layouts caused the program to spit out garbage.

The headers used in the professor’s book became obsolete, so I ended up copying the EXT2 header file from Linus Torvalds’ GitHub.

I figured this part out when started reworking the project a few months ago. I realized that I was missing so much knowledge about the abstraction layer just below the general applications. Now Ritchie and Kernighan’s book gives me an added layer of context. It helps connect many fragments in my head together.

Final Thoughts

I am planning to pick the project up again. I think I left it in a good state.