Wednesday, June 16, 2010

Single-line blocks: A radical view

For a long time I've been a staunch advocate of using braces around single-line blocks in C-like languages:

            // OK
            if (foo)
            {
                return 1;
            }


            // Bad
            if (foo)
                return 1;

The obvious reason is to protect against this kind of bug:

            // very Bad
            if (foo)
                Debug.WriteLine("returning 1"); // added later
                return 1;

There's actually a bug in Visual Studio that we shipped because of this kind of mistake. If memory serves, it was in VS 2002. The repro:
  1. Start debugging.
  2. Open the watch window
  3. Make a Remote Desktop connection to the session running the debugger
Result: 

  • The font in the watch window changes to the system font (big & ugly).
The problem here was a bit of code in DllMain of a debugger DLL where a single-line block didn't have braces, and then another line was added later. Turns out DllMain gets called when connecting in a RDP session. The Watch Window font gets deleted prematurely. This was in the early days of Terminal Sevices / RDP, so it took us a little while to get cluefull (opposite of clueless!).

It would have helped if we auto-formatted our code, but we didn't like what the C++ auto-formatter did by default, so we didn't run it.

Since then, I have argued that all single-line blocks must have braces, to prevent this kind of bug.

Later I started reading about Extreme Progamming, and their radical views on simplicity. I decided that simple, single-line blocks are a nice goal, because they mean your code is simple. So, I now have an exception to my rule. A single-line block can skip the braces if 1) it is on the same line as the if/for/whatever statement, and 2) the whole line is short. Also, I consider this state of affairs is particularly desirable.

So:
            // Good
            if (foo) return 1;
            else if (bar) return 2;
            else return 0;