Common programming errors and how to avoid them

October 8, 2009 – 7:02 pm Tags: ,

Back in august, I introduced the error tracking challenge. While it didn’t get as much participation as I had hoped for, I did manage to collect some results.

In this post, I’ll go through the most common ones, and suggest some approaches to avoiding them. Suggest your own errors and tips in the comments!

Boolean logic errors

This was the most commonly encountered problem. I have also made mistakes with boolean logic more than enough times.

Boolean logic errors usually manifest in if-else statements, as they are the main pieces of code where you may run into complex statements to determine what to execute.

There are various ways to avoid these, ranging from utilizing OOP better to splitting up conditions to multiple statements:

  • Split conditionals into multiple statements: As this tip’s name says, split your complex conditionals over multiple statements. Not only will they be more readable, they can convey the meaning much better.
    if(!($user->level == 1 && in_array($bannedUsers, $user->id) || 
      $page->name == 'index') {
      ...
    }
     
    //vs
     
    $isMainPage = $page->name == 'index';
    $notBanned = !in_array($bannedUsers, $user->id);
    $loggedIn = $user->level == 1;
    if(($loggedIn && $notBanned) || $isMainPage) {
      ...
    }

    I had a better example in mind from some recent code I modified, but I forgot it. However, this kind of made-up looking example still demonstrates the point – as you can see, the condition is much cleaner and it’s quite obvious what the requirements for the if-clause passing are.

    In fact, while writing the above example, I almost made a logic mistake.

  • Utilize OOP and polymorphism better: Often an if-else may be used to determine some course of action. In many cases, this could simply be abstracted into a class, and the concrete implementation of it would determine the course of action, without the calling code needing to use if-elses.

    There’s a great Google Tech Talk about Inheritance and polymorphism which shares a great deal of information on how to avoid conditionals completely.

Typos or unintentional omissions

Typos and omissions are some of the most common issues people told me about. Typos should be quite obvious: Misspelled variable names, function names and such. Unintentional omissions may be a little less clear at first – By omissions, I mean things like forgetting to remove debug statements, forgetting to upload a file or other things like that.

I’ve grouped these two mistakes under the same headline, as they belong in the same category: Mistakes caused by not paying enough attention, or in other words, being sloppy. Another cause is plain and simple forgetfulness.

While these two aren’t always very fatal mistakes, they can be problematic and annoying. For example if you check in code with typos or omissions to source-control and your coworkers get broken code.

How to avoid typos?

  • Use a programmer’s editor or an IDE. They will often support code-completion and are often able to highlight misspelled names
  • Write slower: While this sounds really obvious, you might not really need to type that fast. While I personally take some pride in being a fast typist, sometimes it’s just difficult to write things correctly when you’re simultaneously thinking about things like implementation details or how to name your variables etc.
  • Become a better typist: The opposite to the above, by becoming a better typist you can write faster and make less mistakes. While learning to be a fast writer may not rank very high on your to-do list, there are ways to make it quite fun. A good example is Typing of the dead
  • Get a better keyboard: Your keyboard may not be bad per-se, but perhaps you’d be more comfortable typing with a different one? I’ve noticed some changes in my correctness after getting a Logitech Wave keyboard to replace my aging Microsoft Multimedia Keyboard

A reader also suggested learning to use the dvorak keyboard layout instead of qwerty. If you have the patience to suddenly become the world’s slowest typist for a while when learning the new layout, this may be a fun and useful skill.

A spelling corrector may also be a good thing to have at hand.

What about omissions?

  • Read through diffs: Before commiting code to source control or creating a build, you can save your and everyone else’s time by going through the diffs for your changes. Not only will this let you spot any accidental omissions, you may actually spot a genuine bug while at it. Even better, you might want to get someone else to review the code with you
  • In general, version control tools like svn and git are good for avoiding omission-like mistakes. They can display you a list of modified files, unversioned files and other such things, which can help you find the errors.

Debugging mistakes

While not strictly a programming mistake, these are very much related.

Debugging mistakes can be so many things that I’m not going to go into all specific details. However, there is one common occurence: Wrong debug methodology.

How do you know your debug methodology is wrong?

You constantly go deep into code to figure out some problem, and it turns out it was something really simple, such as a missing file.

The old IT support mantra comes to mind:

- Is it plugged in
- Is it powered on
(repeat for each peripheral)

While this appears in various tech support jokes and such, this is a valid methodology: By ruling out the mistakes that are easiest to detect, you can save a lot of time if it was one of them.

Quite recently, I worked on some code that needed to be built to run. I could debug it from the IDE without building, and for some reason the code worked perfectly well in the IDE but not with the build.

I probably spent an hour or more, looking into various internals of things that seemed to be causing the issue. In the end, it turned out the build script was broken: A new directory I had added wasn’t included in the build, breaking the application.

If I had checked the relatively easy to test issue of having all directories in the build, I could have saved much time.

If you have a bug that seems elusive, check the obvious things before spending a lot of time debugging it. It may end up saving you much time and nerves.

JavaScript closure misunderstandings

While the other problems aren’t language specific, this one was also common enough to include in the list.

JavaScript closures can be very confusing if you aren’t used to them. I used to get confused by them all the time.

The typical mistake looks like this:

var obj = {
  prop: 10,
 
  myFunc: function() {
    alert(this.prop);
  },
 
  otherFunc: function() {
    setTimeout(this.myFunc, 100);
  }
};
 
obj.otherFunc(); //does not alert 10 correctly!

While the problem here is obvious to JavaScript veterans, it’s not so easy for beginners – even if they’re experienced in programming otherwise!

The fix to above is to wrap the timeout call:

var self = this;
setTimeout(function() {
  self.myFunc();
}, 100);

I won’t go into more details here, but there’s plenty of material on JS closures on the web.

What did I miss?

Out of the dozen or so mails, these are the most common ones. I was hoping to list at least 10, but due to lack of participation I couldn’t.

Do you have a common problem you encounter when programming? Do share it, or your other tips , in the comments!

Share this:
  1. 8 Responses to “Common programming errors and how to avoid them”

  2. Hi, Jani.

    I said I’m in but didn’t send you the report. I totally forgot about the game we were playing! Sorry about that.

    The most common programming error I was doing recently was re-factoring code without tests. Although, I was making minor function name changes here and there, without testing the changes turned out to be a big mistake. I had introduced new bugs in the application.

    If you are making changes to the code, test it. Test can be in any form – manual testing or unit testing. At least run your code through lint checker. php -l can be very handy.

    By Sudheer on Oct 8, 2009

  3. That’s a good tip Sudheer. I totally agree that being without tests when refactoring a working app is something you don’t want to do.

    By Jani Hartikainen on Oct 8, 2009

  4. A tip for people that are really new to programming:
    When you do things such as IF statements that require an opening and closing character you should type both opening and closing characters before entering code into it so you do not forget to close your statements.
    (Note: Most modern IDE’s auto close common characters)
    So first do:
    if(XXX != ABC){

    }
    -Now Enter Code-
    if(XXX != ABC){
    // Code
    }

    By CodeJustin on Oct 9, 2009

  5. You might echo or print certain variables out to the screen while developing code or fixing errors.

    A good tip is to define a function to do this in a certain way.

    Here’s mine that only shows the debuggin code to me and prints it out nicely to the screen:
    function print_only_to_ip( $var, $var_name = ”, $ip = ‘xxx.xx.x.xxx’ ){
    // if the site is not on the local server show the code and the IP does not match Don’t show the code
    if ( strpos( $_SERVER['SERVER_NAME'], ‘sbs’) === false && strcmp( $_SERVER['REMOTE_ADDR'], $ip ) 0 ) {
    return;
    }
    echo “only to ip $ip \n\n$var_name \n\n”;print_r( $var );
    // var_dump(debug_backtrace());
    echo ”;

    }

    I call the function like this,
    print_only_to_ip( $varToPrintToScreen, __LINE__ . ‘ ‘ . __FILE__ );

    Using the __LINE__ and __FILE__ magic constants ensures I never have any problem finding the place in the code where I’m echoing the code.

    You could also add the line to the function to print out the debug backtrace line and file.

    By Delazee on Oct 9, 2009

  6. The absolute worst mistake is the way people name variables ans functions

    I always try and give things meaningful names e.g.

    $sName ( ia a string )
    $objResult

    It mean’s more typing but defo makes reading the code easier

    By sean on Oct 9, 2009

  7. Great post Jani, as always.

    Another tip to avoid hard-to-spot errors is writing

    if (‘something’ == $someVar){}

    rather than

    if ($someVar == ‘something’){}

    With the second form, it is very easy to write a single = and this will always evaluate to true, without a parse error in many languages!

    By David Caunt on Oct 10, 2009

  8. Do NOT “Split conditionals into multiple statements”!

    Just check out this sample code to understand:

    It will output “echo1.echo2.end”.

    By Julius Beckmann on Oct 10, 2009

  9. I don’t think your sample code quite worked out…?

    By Jani Hartikainen on Oct 10, 2009

Post a Comment

You can use some HTML (a, em, strong, etc.). If you want to post code, use <pre lang="PHP">code here</pre> (you can replace PHP with the language you are posting)