There is one single source of most bugs. It’s obvious, yet almost nobody talks about it. That source is statistics.
You can call it a stretch, but it’s true. No matter how you classify a bug, whether it’s a race, a leak, whether a programming error, a typo or a misunderstanding, statistics influences whether that bug occurs or not in the first place.
Using mallocs/frees all over the code or using lots of gotos is not a source of bugs per se. Most occurrences of constructs widely perceived as bug prone will not produce an incorrect program. Until these constructs meet statistics.
If we put it this way, it sounds hopeless, because statistics quantifies everything around us, every programming technique. But we can use this fact to choose which programming techniques we use or even as far as which programming language we use, to reduce the number of bugs.
Using the above example, if we write a program explicitly calling malloc() and free() to allocate and release memory as needed, we will occasionally forget to call free() and introduce a memory leak in the code. In C++ the simplest solution to that is to never use free() or the delete operator, but to rely on destructors to do their job instead (e.g. the use of std::vector or std::make_shared() in C++11, etc.). This way we will never forget to free memory, the compiler will do this for us.
This post is meant to serve as advice for beginner programmers. If you don’t consider yourself a beginner, read on and check if you agree.
So here are a few basic principles which a programmer should follow to write good code, no matter what the language is.
When I started my adventure with programming back in fall of 1993, I wish somebody laid these out for me. There are many good books about the dos and don’ts of programming, such as Effective C++, but I think it’s still difficult to find to find the more simple basic principles like the ones below, esp. for novice programmers.
These principles apply to most areas of programming. They should be taught at the beginning of programming courses. Unfortunately most programming courses focus on tools, such as programming languages, environments, data structures, etc. but they don’t touch the craft and art of programming.
Copy & paste
When writing one of my first programs in Turbo Pascal, I quickly learned that pasting pieces of copied code around in a program leads to a lot of unnecessary work at a later time. Let’s say you have exactly the same piece of code in N places, and that code is meant to do the same thing, or even if there are N places with very similar code doing very similar thing. One day you will have to change that code slightly or enhance it. Or you will find a bug in that code. You will have to find all N places and apply the same change N times. There is a high probability that you will miss some of the places – the larger the N the higher the probability. This will lead to either not fixing existing bugs entirely or introducing new ones.
The takeaway from this is that multiple copies of the same pieces of code should be avoided. Similar code should be collapsed into one function and that function invoked wherever it’s needed. Avoid copy & paste.
Variables, functions, members etc. should be named after what they do. Most variables should be nouns. Most functions should be verbs (e.g. variable num_args vs. function count_args()). The names should be short, but long enough to give a clue to the reader what they mean. There are some schools which teach that variables should never have long names. This is OK, but in some circumstances it’s necessary to give longer names so that the reader can easily understand what is happening in the code.
There is another term for using meaningful identifier names: self-documenting code. When clear names are used, there is less need for comments and other kind of documentation.
Comments should be used whenever the names of variables, constructs etc. are not sufficient to understand what’s going on. This applies especially to more complicated pieces of code, algorithms, etc.
But why bother with all of this? One word: maintenance. Sometimes a person other than the author has to maintain the code – fix bugs, add new functionality, refactor or reuse. The less time that person needs to spend to understand what’s going on, the better. Often even the author may need to return to the code he’s written and may not remember why certain decisions were made.
Language constructs which promote bugs
Every language has constructs which promote bugs. Such constructs should be avoided. They may be useful or necessary in certain situations, but in these situations they are the necessary evil. In most other cases we’re better off without them.
In general any language feature which has gotchas, which may behave in an unexpected way (e.g. friend or protected in C++), should be avoided, unless specifically beneficial in a certain situation. When used, precise comments should be added describing the use case.
The unfortunate thing is that until you know a particular language really well, you don’t know what these tricky constructs are. They are usually not advertised in the language manuals. Sometimes there are books which help to learn about why particular features are dangerous. So the best advice one could give here is: stay alert!
Diligence vs. ignorance
The advice here is: be diligent. Learn about the environment surrounding the code you write (i.e. callers, callees, etc.). Learn about all the use cases. Try to think of all things that your approach may break. It does take experience to write good code, but it also takes common sense.
It’s good to have an additional pair of eyes review your code. If you’re writing code for fun, have a friend take a look at it. If you’re working for a company, have a coworker review your code and review his code in return. I don’t know why code reviews are not a custom at many companies. Reviews take only a small amount of time, but they have a big benefit of unifying the code to ease future maintenance, promote coding style conventions, promote good behaviors and suppress the bad ones, etc. It’s even more beneficial if somebody more experienced reviews your code, you will learn from him.
Reviews are not an ultimate solution, they will not help to find all bugs, in fact many bugs will slip through reviews, but reviews help improve code quality in the long run.
A post in a new category – movie reviews. Hopefully everyone’s favorite. 🙂 This new category will in fact be not only about reviews, but also about my commentary.
The Thing is a movie about an alien lifeform which crash-landed on Earth in Antarctica long ago. It’s actually a prequel to John Carpenter’s original movie from 1982 with the same title.
If you like movies about evil aliens like I do, you would certainly like this one. The prequel blends very well with the original movie, in fact it at the end it is surprisingly well connected to the original. They did not overdo the monsters but made them more believable using current technology. There is a lot of action in it, boring scenes were kept to a minimum to sustain the story. Definitely worth watching if you like thrillers, action and aliens.
The lifeform in the movie is bloodthirsty, but it does not only want to just consume Earth’s lifeforms. When the organism catches and swallows a dog or a human, or even if it only sprinkles one with its fluids, the alien cells attack prey’s cells and convert them into alien cells.
It wasn’t said in the movie, but one can suspect the alien lifeform attacked some other intelligent aliens who had a spaceship and this way came into the possession of that spaceship, which it used to come to Earth. This could potentially explain why a graceful landing would be too hard for that creature.
What does not make much sense is how such lifeform with the ability to understand and pretend other lifeforms from other planets could evolve in the first place. All lifeforms are bound to their environment. They are used to pressure and chemical composition of that environment. Advanced organisms don’t have the flexibility to live in environments beyond their home, because they are too complex for that. I find it hardly believable that a species from another planet could come to Earth and breathe our air, eat our meat, let alone have the ability to change itself into one of us in a matter of minutes.
However there is one scenario in which such a life form could be possible – if it was deliberately created as a weapon or even just as a crazy experiment.
But even if such a lifeform existed, I still find it quite improbable that it could find another alien with spaceship technology who it could mimic. I would argue, that civilisations able to travel in space to other planets must have evolved beyond physical limitations of biological life and consist of cybernetic beings, which we today consider as “robots” or “androids” etc. For this reason I think that even if such a creature existed, it wouldn’t be able to spread effectively to other planets.