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 there 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:
Continue reading “Hidden Dependencies”
Polymorphism is something usually associated with Object Ortiented Programming, not with classic C. However, the notion of Polymorphic behavior defenitly exists in C in a “lighter” form. You will not automatically get all the back-stage mechnisms 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 tradeoff 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 wokring only on ‘int’ arrays.
Continue reading “C Polymorphism – Part 1”
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:
unsigned int type_size_in_bytes;
unsigned int num_of_elements;
// This will point to the allocated array of instances
char * p_array;
Continue reading “C Polymorphism – Part 2”
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?
Continue reading “The Dreadful ‘Goto’”
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 any other reason.
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:
Continue reading “Masks VS. Bitfields”