Category Archives: C/C++/Embedded

The Principle of Proximity

pebbles.jpgIt is common wisdom that opposites attract. In programming, however, it is desirable to keep things that are related together — that’s at least what the “Principle of Proximity” states.

This principle has many manifestations, some of which are well known by most software developers, for instance:

-Keep the documentation (comments) as close as possible to the code;
-Initialize variables as close as possible to the point where you use them;
-Limit the scope of declarations (i. e. use namespaces and don’t make constants public if private is sufficient);

As opposed to opposites, related things not always attract, or — as a matter of fact — attract in a suboptimal way.

Here is an example. Assume that you have to process a list of different objects (let’s call them “boxes”, for the sake of this example) that you have just received, maybe over a socket connection. This list always consists of a blue box, a red box, and a green box, exactly in that order. These boxes are encrypted and protected by an integrity checksum. Before actually processing them, you need to perform decryption and integrity checking. (Also assume that the boxes are completely different. They have different content, different security mechanisms, and require different processing.) Below is one way to go about it:

At first glance, this code doesn’t look bad at all. It is grouped in such a way that the three steps are clearly visible: 1. get a box; 2. apply security to box; 3. process box. If you zoom out a little, the structure looks like this:

Is this the principle of proximity in action? Are related things close together?

Not really. The things that are close together are the objects under each operation, but the objects themselves have little in common. Contrast this with this approach:

The structure is now inverted:

The objects and their operations are close together; in fact, they are completely encapsulated. I like to call this ‘encapsulation at runtime’, which is not to be confused with traditional object-oriented encapsulation where you put data and its related operations close together at coding time, in a class. (Which is another instance of the principle of proximity, BTW.)

What I don’t like about onReceiveBoxes1 is that it mixes up things that are unrelated: order of boxes and order of box actions. Just because the boxes are ordered in a particular way, doesn’t mean that we have to perform the box actions in that particular box-order. Unnecessary dependencies are usually bad for maintenance.

Ah, maintainability, that’s where the second implementation really shines! If you have to add a yellow box someday, you just copy and paste the block of an existing box and do some minor modifications. And if the order in which boxes arrive changes, adapting onReceiveBoxes2 is likewise trivial. Better maintainability means that the risk of introducing an error is much lower, which in turn means that you spend less time debugging and have more time for doing code katas.

Honoring the principle of proximity almost always gives you better efficiency, either. Notice that in the first implementation, the pointers to all boxes have a fairly long lifetime and must be kept in memory (or CPU registers) as they are needed until operation 3 has finished. onReceiveBoxes2 only needs a pointer to the box that is currently worked on, which means that the compiler only needs to allocate one pointer.

Code Kata 2: The “Average” Developer

You might be tempted to think that calculating the average of two integers is a trivial thing. If you think that it is as easy as this:

you are wrong. But don’t be depressed — you are in good company. Code like this is written every day — not just by average developers.

(Task#1: Hold on for a minute. Can you spot any problems with this code?)

I’m not talking about the fact that the result is not precise — it can’t be, due to the limitations of the integer type. If ‘a’ is 5 and ‘b’ is 6, the mathematically correct result is 5.5. With integer division, however, it is 5, which is perfectly OK for our purposes; otherwise, we would have used ‘float’ or ‘double’. No, that’s not what I’m looking for…

The trouble is that if a developer looks at the signature, (s)he will probably think “Well, this function takes two integers and returns their average value. I can pass ANY unsigned integer to this function.”, which is of course not true. Why? If the integers are large enough, their sum will overflow the unsigned int range and hence the result of the division will be wrong. There you have it!

(Task#2: Write tests that show when and how overflow happens.)

You could use a larger type internally:

but maybe ‘long long’ is not available on your platform, or you are already using ‘long long’ and there is no bigger type, or you simply don’t want to sacrifice efficiency, especially by using a floating point type. (Note that ‘long’ is not sufficient in our example as on 32-bit platforms ‘int’ and ‘long’ are usually of the same size). So how can you solve this problem without resorting to a larger (more expensive) type?

Years ago I found a solution (I don’t claim that I’m the first who invented this, and I won’t be the last to reinvent it, either) by reasoning like this:

In pure mathematical terms, with a mathematical division operator, (a + b) / 2 is identical to a / 2 + b / 2. By applying this principle — and “wasting” another division — one could avoid the dreaded overflow in the sum. Unfortunately, integer division doesn’t exactly work like mathematical division. For instance, if ‘a’ is 5 and ‘b’ is 7, (5 + 7) / 2 is 6, but 5 / 2 + 7 / 2 = 2 + 3, which is 5. So it is possible that the result is one less than what we expect. How can we compensate for that?

Here is the insight: For both divisions, the integer division operator leaves a remainder behind and if the sum of the remainders (of both divisions) is equal to two, we have to add 1 to our result. Think of it this way: in such cases, the sum of ‘a’ and ‘b’ contains a 2 more than the parts of the sum themselves:

Here is an implementation that applies this correction:

Unfortunately, this is not only ugly, it is not very efficient, either. Now we have two divisions, two modulo operations (which are as expensive as division operations), two additions, an if-statement and an increment operation. But as every bit-fiddler knows, there is a simpler modulo operation for divisors that are a power of two:

Equipped with this knowledge we get:

Which is identical to:

In C, results of boolean operations are either 0 or 1 (in C++, they are ‘false’ or ‘true’, but ‘false’ and ‘true’ are converted implicitly to 0 or 1 in arithmetic expressions), so we can shorten our average function:

Cool isn’t it? But it’s not unlikely that your compiler will apply these optimizations for you automatically, in case you write your code like in the first, ugly solution. But it certainly won’t add the correction that is missing from the first implementation — trust me on this one.

(Task#3: Write a small program that uses this implementation of average() and test it.)
(Task#4: If you change the types used by average() from ‘unsigned int’ to ‘int’, will the code also work, specifically for negative values of ‘a’ and ‘b’? Why? Write some tests to proof your theory.)
(Task#5: Implement and test an average4() function that calculates the average of four integers.)

A Small Matter of Style?

Some claim that there is a reason for everything. Well, I’m not so sure about this statement, but surely there is a reason for Code Kata 1: it was inspired by a routine that I found in a real-world product some time ago. It looked more or less like this:

The job of this routine is to find a value in a vector that matches the given reference value as close as possible. It works by visiting each element of the vector, calculating the absolute difference to the reference value and, if the new difference is smaller than the previous, updating the ‘bestIndex’, the index of the value that matches best.

This routine has proven to work reliably, at least no errors have been found so far. But in my view, it nevertheless leaves a lot to be desired. Let’s dissect this code step by step.

First of all, there are no comments, but I don’t think this is a big issue here. In my view, the code is quite short and the identifier names give sufficient meaning.

The most noticeable peculiarity about this code is the hideous floating point literal 1.7976931348623158e+308 on line 3. What the heck is this?

If you study the for loop and find out how the algorithm works it becomes clear: ‘bestDistance’ is initialized to the largest possible value such that the condition on line 8 becomes ‘true’ for the first element, in order to get a first candidate.

But using a hard coded floating-point literal is the worst approach to achieve this. Why not use ‘DBL_MAX’ (from cfloat/float.h) or ‘numeric_limits::max()’ (from limits)? Especially the former is much easier to type, less error-prone, and you get portability for free: recall that the limits of numeric types are not fixed in C++ (for double the upper bound is specified to be at least 1E+37, but that’s about all that the language standard promises).

The algorithm itself is not perfect either. Like I said, during the first iteration, the comparison on line 8 will always fail as ‘bestDistance’ is initialized to the largest possible value. Why not save one iteration by initializing ‘bestDistance’ to the distance between the reference value and the first vector element? Sounds like a good idea, but this approach will work only if we know that the vector is not empty. Which brings us to the topic of the odd way in which errors are handled in this routine.

Have a look ath lines 14 and 15. The routine returns the found ‘bestIndex’ only if it is within the bounds of the vector; otherwise it returns -1 (for failure). Under what circumstances is it possible that ‘bestIndex’ is outside the range of the vector? It turns out that it can’t — unless the vector is completely empty. So why not make this check explicit and put it near the top of the routine before the actual search starts?

Here is an improved implementation, based on my previous observations:

But I’m still not happy with this routine: as it stands it works for doubles only, but isn’t it of general utility? The code would be identical for vectors of chars, ints, pointers, and complex numbers. Why not turn this code into a template function such that it can be put in a library?

There is a snag, however. The code uses ‘fabs‘ a function that returns the absolute value of a floating point value. We need it to be able to compare the distances of vector elements to our given value, but it only works with floats/doubles and ‘abs’ is for ints/longs only, so we cannot write truly generic code. But wait a minute, doesn’t cmath provide overloaded versions of ‘abs‘ that work with all types?

So our generic implementation could look like this:

Looks neat, but we still have a problem: for simple scalar types, we can assume that ‘abs’ looks like this:

which means that the return type is the same as the argument type. Hence, code like

is perfectly fine.

But for complex types, like complex<>, the picture is different as complex is itself parameterized by a type:

and according to the mathematical definition, the return value of ‘abs’ on a complex number is not a complex number but rather a real number:

Therefore, if T is complex<double>, this line

doesn’t compile: ‘bestDistance’ is of type complex<double> but the return value of ‘abs’ is double.

Are we stuck in a rut? Sometimes the result of ‘abs’ is T (eg. for int, float), sometimes it is something totally different (eg. for complex, valarray, pointers). It looks like we cannot provide a truly generic implementation.

Not so fast! If we use C++0x and one of my favorite features, automatic type inference, we can:

The ‘auto’ keyword is magic: in C++0x a variable declared as ‘auto’ gets the type of the expression that is assigned to it — what a great tool for developing generic code!

There you have it. Even though the original code worked fine, the final version is nicer: it provides better readability, portability, and genericity. On top of that, it is theoretically slightly more efficient because it saves one redundant comparison. Why theoretically? Because I haven’t measured execution times. What a breach of style. Shame on me.

The Beauty of Imperfection

leaves.jpgThere once was a master programmer who wrote unstructured programs. A novice programmer, seeking to imitate him, also began to write unstructured programs. When the novice asked the master to evaluate his progress, the master criticized him for writing unstructured programs, saying, “What is appropriate for the master is not appropriate for the novice. You must understand the Tao before transcending structure.” (from The Tao of Programming)

Some time ago, I worked on a little command-line tool, when all of a sudden I stopped. Did I really just use a ‘goto’ statement?

What surprised me most about this code was that I didn’t feel any sense of guilt; somehow, it was just natural to use a ‘goto’ in this context.

Isn’t it considered harmful to use ‘goto’ statements? Or global variables? Or public attributes instead of using accessor methods? Or to duplicate code and data structures? In general, I think it is (of course) but there are circumstances when it is perfectly OK to write such “imperfect” code: If you know what you are doing and if you sacrifice perfection for a higher-level goal. This is very similar to a gambit in chess-playing: you trade a piece for a strategic long-term advantage over your opponent.

In my case, the higher-level goal was to actually do write a little tool for my personal use that allowed me to do things automatically — things I used to do manually (and due to the pain of manual work, frequently omitted). Granted, it would not have taken much effort to put the error reporting code into a routine of its own. But I guess that if I had spent enough time thinking about all software quality aspects like readability, testability and documentation, I would have never written this otherwise useful tool. It’s always better to have a tool that saves you from manual labor but uses goto statements than no tool at all. So my use of a ‘goto’ is just one particular manifestation of my “go-as-fast-as-possible-or-it-will-never-be-done” mindset.

You could also call this style of programming “deliberate hacking”: you know that you do something suboptimal but you do it on purpose for good (sometimes noble) reasons. This style of hacking should not be confused with bad hacking, where you write bad code either unconsciously or consciously for a bad reason (like pure laziness or obscuring your code to make yourself indispensable).

It is a good idea to keep software quality gambits in the private implementation details, where as little people as possible are affected. As a C programmer, do you care about any hacks in the ‘make’ program’s source code? Most likely not! However, many ‘make’ users complain about the fact that ‘make’ is whitespace sensitive: you have to use TAB characters to indent build commands — spaces may result in obscure errors.

For sure, a software quality gambit increases technical debt, but it is important to note that you get an asset with a much higher value in return. Ideally, the value of your asset doesn’t decrease (or only slowly decreases) over time, so that the technical debt isn’t noticeable or at least doesn’t harm. I’m convinced that the decision to use TAB characters in ‘make’ was a good hack at the time, but its asset value has long become zero. One possibility would be to change ‘make’ such that it works with TABs and spaces, but is it really worth it? For instance, how confusing and annoying would it be if makefiles that use spaces (and work with the latest version of our imaginary ‘make’) result in obscure errors on systems where only older versions of ‘make’ are present? It’s probably the best to embrace this historical beauty mark as a given fact.

In general, I think we must fight perfectionism in software development to avoid losing track of our main goal: shipping working software with good enough quality. Next time you find a hack, try to understand its nature and motives. Was it a good hack or a bad hack (frequently good hacks are marked with explanatory comments, like TODO comments). Maybe you can even develop a sense for appreciating such good hacks. This is akin to “Wabi Sabi“, a Japanese art concept. Wabi Sabi is sometimes described as seeing beauty in things that are imperfect, impermanent and incomplete. Wabi Sabi art acknowledges three simple realities: nothing lasts, nothing is finished, and nothing is perfect. I think we should accept these realities for software as well.

Code Kata 1: The Closer You Get

I’ve already written about Code Katas and how they can help you become a better programmer; this time, I’m getting serious about it.

Like all craftsmen, we need to practice a lot; eight hours of professional software development is not enough, especially if a great share of these hours is dedicated to email and meetings. A carpenter is not just building houses but also tries out new ideas on his workbench in the basement; painters sketch and explore new combinations of paint and color. Photographers do it, musicians do it: everyone who wants to become better at their craft has to practice in a safe and dry place.

Today’s kata is a simple one. Imagine you have a set of numeric values. If I give you another value (which may or may not be within the set), find a value from the set that matches the given value as close as possible. Don’t write any code yet! Proceed as indicated below.

  1. Think about the problem and draw a picture that illustrates the problem.
  2. What special cases do you see?
  3. Try to come up with a simple algorithm (use pseudo code, flowcharts, whatever you prefer).
  4. Write down a few good test cases and mentally check your algorithm against them. Select a programming language of your choice and code a dummy implementation that always returns the same (wrong) result.
  5. Code your test cases and execute them against your dummy implementation. You don’t have to use unit testing frameworks like JUnit; use the simplest way of comparing results to expected results and flag an error if there is no match.
  6. Watch your tests fail.
  7. Implement your algorithm.
  8. Execute your tests and debug your code until all tests pass.
  9. If you haven’t done it yet: single-step through every line of your code.

Bonus exercise:

  1. Turn your algorithm into a generic routine that is suitable for a library; that is, support different value types (floating point types, integer types).

Comment-Driven Development

comment.jpgMany developers hate documenting their code: They view writing comments a nuisance, something that slows them down. All they want to do is get the darn code to run; comments just mess-up the code and — behold! — are for wimps, anyway.

Sometimes even followers of this school of thought write comments, but these comments are frequently a mixture of self-indulgence, inside jokes or just plain insults:

Then there are folks who take the exact opposite position. They want comments everywhere. They believe that comments should be of such a density, that by just reading the comments they would get a perfect understanding of the whole system. Never would they have to look at such ugly things as — behold! — source code again.

Like it or not: I have observed that many of the highly gifted developers belong to the first group.

But let’s face it: neither position is right. As professional software developers we need to understand that we have an obligation to preserve the value that we create. Good comments do help understanding the code and thus improve maintainability and we are in maintenance mode most of our lives. Like the old saying goes: “Be nice to the next guy”; and often that next guy is you (or me).

On the other hand, crafting good comments is hard and time consuming and as professional software developers we also have an obligation to spend the resources of our companies or clients prudently. Therefore, we need to strike a balance: sometimes it is best to leave the nitty-gritty details for the code.

My rules of thumb so far have been:

1. Focus on good layout and self-explanatory identifier names.
2. Explain the WHAT and not the HOW.
3. Comment surprises; that is, unexpected/unusual things.
4. Comment all non-private parts (public, protected, default)
5. The more public, the more detailed the documentation has to be.

I used to defer writing API documentation comments as long as possible. My reasoning was that otherwise I would have to update/rewrite the API documentation while iteratively developing my code, which I considered a big waste of time and energy. But I’ve changed my mind completely in this respect.

I strongly believe that writing the API documentation before doing any coding is a great benefit. By clearly spelling out the purpose of a piece of code, developers engage in a brainstorming session with themselves that leads to further insights. Until this purpose cannot be stated concisely there is no point in doing any coding. Let me repeat that: If you cannot crisply describe WHAT a method or class is supposed to do, you shouldn’t start implementing it. Granted, most developers do have at least a partial model in their mind before they start coding. If they would also write it down, they could win in several ways.

Naturally, even API documentation comments need to be developed iteratively and often need some fine-tuning during the course of implementing the API. In fact, the process is very similar to test-driven development: One of the biggest benefits of TDD is that by writing tests before doing any coding, you imagine (and in fact see and experience) how the interface is used by clients early on; that’s valuable feedback which helps getting interfaces better. The same holds for the WHAT of a method or class as well.

The notion of writing comments or documentation before doing the coding can be extended to the implementation of a routine as well. In his landmark book, “Code Complete”, Steve McConnell describes a comment-first process for implementing a routine called “Pseudo code Programming Process”: You start by typing in the high-level steps that a routine takes, in plain English, using vocabulary from the problem domain:

Once your are satisfied with your pseudo code, you fill in the real code. As a final step, you turn the original pseudo code into comments — voilĂ !

[Note: I know that this example is a little bit contrived. A cooler implementation of CalculateTaxRate() would return a tax rate of zero in case the income is below the threshold. This would result in shorter, branch-free code.]

Writing good comments is essential for every professional software developer. Since writing comments is hard, it is usually left out if it is considered an afterthought, especially under deadline pressure. If it is done upfront, it can serve as a valuable design tool that yields great documentation for free.