Goto be gone! Long live do {} while!

Part of my role at QNX is to be ornery about source code style, formatting, consistancy and the like. Obviously a very popular role to fill =;-)

One of the particularly religious debates that we occasionally get into revolves around the use of the goto statement. There are many people who use the goto statement considered harmful to argue that there is no rightfull place for a goto in our code.

This attachment to a particular dogma means that for complex structure initialization code developers often end up running a series of if clauses initializing each member of the structure in turn. If the code properly deals with errors and rollsback to undo the initialization, you end up with one of two scenarios:

  • If progress stops on initialization failure, then each if clause ends up having a growing list of clean up items on failure. A good compiler will optimize this, but it is too easy to forget an item and end up with a resource leak of one sort or another.
  • If progress continues, then you end up with a deeply nested if statement where the final return (on success) lies deep in the heart of the nesting. The cleanup for resources is generally straightforward, but in many cases the cleanup lies so far away (in code editor space) that it is cumbersome to read.
  • For this reason, I’ve always appreciated the goto statement as acceptable for these types of “go to a cleanup” scenarios where you have a large initialization dependancy (as might happen in a QNX resource manager) and want to group the cleanup so as to improve the readability and reduce the chance of an accidental resource leak. Unlike the use of goto resulting in spaghetti code flow control, this is a much more tempered use of goto statements in C code.

    However, the other day I was participating in a code review and came across an interesting use of the do {} while
    loop to achieve a similar early exit, but without all of the contempt of those who think that goto should be removed from the language all together:

      //Structure declaration and initial allocation here
      do {
        // ... Member initialization here
        if(failure) {
          break;
        }
        ...
       //Return successfully allocated and initialized member here
       } while(0);
      
       //Cleanup and failure reporting all goes here
    

    Here you get a nice linear, easy to read and maintain flow of code initialization without being burdened by the error condition flow control that a nested if requires or the deep unrolling of initialization that a chained if requires.

    In any case a nice escape away from goto’s; even though Dijkstra never said goto was considered harmfull =;-).

    About these ads

    No comments yet

    Leave a Reply

    Fill in your details below or click an icon to log in:

    WordPress.com Logo

    You are commenting using your WordPress.com account. Log Out / Change )

    Twitter picture

    You are commenting using your Twitter account. Log Out / Change )

    Facebook photo

    You are commenting using your Facebook account. Log Out / Change )

    Google+ photo

    You are commenting using your Google+ account. Log Out / Change )

    Connecting to %s

    Follow

    Get every new post delivered to your Inbox.

    %d bloggers like this: