We want our code, in C or C++ in this case, to be as robust as possible. By “Robust” I mean resilient to bugs, changes and surprises. We can increase our code’s run-time robustness by employing various good coding practices, “assert” constructs or even just ‘if’ statements in the right places to protect against broken assumptions and other dire straights. But wouldn’t it be so much better if we can catch problems before even running a single line of code? The C_ASSERT macro will do just that.
Polymorphism is something usually associated with Object Oriented Programming, not with classic C. However, the notion of Polymorphic behavior definitely exists in C in a “lighter” form. You will not automatically get all the back-stage mechanisms OOP languages give you, but there are still time in which you can get a lot of code cleanness by manually applying some polymorphic principles.
The first thing that comes to my mind when thinking about Polymorphism in the context of C programming is pointers to functions. It sometimes allow you to trade-off data with code such that the same general code can handle different tasks without hard-coding the differences. A great (and classic) example to that will be sorting functions. Similar to the OOP Design Pattern in which a general algorithm can be implemented without binding to a specific type as long as it implements the “Comparable” Interface, you can use a similar pattern in C, even if in a slightly more primitive way. Consider the following Bubble Sort implementation working only on ‘int’ arrays.
In the first part of this post, a “classic” example of Polymorphism-like code in C was discussed. Let’s look at some production code I had a chance to refactor. After the refctoring, the code looks like another step forward towards the Polymorphic behavior of real OOP languages. For obvious reasons, I have modified the example such that it is more focused.
The original code used an array of object types. For each one, an array of instances was allocated. The “Type structure” looked like that:
The ‘goto’ operation has a very bad reputation when it comes to high-level programming languages. I have heard many times the sentence “never ever use goto”. I think that the fear of ‘goto’ is generally justified since it can lead to horrible spaghetti code. If really abused, it can completely corrupt the structure of a program, making it potentially impossible to track its logic.
However, I would not go as far as removing it completely from our toolbox. In general, I am careful when I hear those “never use” declarations. The root to goto’s destrcutiveness is actually its overwhelming power – it can be used to jump from anywhere to everywhere in the program (with limits, going really wild is restricted by various languages), breaking through walls, leaving destruction in its wake. Well, if it is so powerful, is it possible that there is good use to it, sometimes?
Achieving Clean Code can get harder when you go down to the nuts and bolts. Bit-manipulating code is very common when you go “low level” with your coding, usually with C. It may be needed when you manipulate HW registers with a certain bit structure, when you want to compress data elements to occupy bits instead of double words or bytes, or for a number of other reasons.
Imagine a register that is used to set the speed for an imaginary communication device. The register can be set with RX speed, TX speed, a “go” bit to propagate the changes and a “ready” bit to indicate when our last “set” operation is done propagating and the HW is ready to work with the new sttings. More formally, it can be put like this:
|31:31||RWC||0||"Operation Done" bit|
|15:8||RW||0xA||TX Speed, in hundreds of Mbps|
|7:0||RW||0xA||RX Speed, in hundreds of Mbps|
The C representation of this register can potentially look like this:
In my humble opinion, creating Hidden Dependencies might be the worst thing you can do in Software Engineering. Claiming that “Hidden dependencies are bad” may sound like a trivial statement, but yet they are all around. People know they should avoid them, but maybe sometimes they just don’t realize that they are creating a Hidden Dependency. Below is a modified example, based on real-life code I was looking at.
Consider the following code. It shows general code that can call functions by enumerated values. Why is useful? For example, it can be a cumbersome way to implement “Polymorphism for the poor” by allowing a data object to express what function is adequate to act on it. Why not use a simple pointer to function? There are examples where the address is not known when the object is being constructed (e.g. an array of objetcts is built offline and are not part of the linkage process, or when one linkage unit (process) makes a call to another (ioctl)). Anyhow, it is valuable for the following example of Hidden Dependencies.
In the code I saw, an enum of functions is defined like this: