Click here to Skip to main content
15,884,298 members
Articles / Programming Languages / C++
Article

A Handy Debugging Macro for Switch Statements

Rate me:
Please Sign up or sign in to vote.
3.55/5 (9 votes)
26 Nov 19992 min read 67.4K   40   3
A macro to help alert you if unreachable is ever reached

Many times when writing switch statements, your code will handle every possible case that the variable controlling the switch could take. For example, if you have a MFC dialog with a combo box or radio button group, with an integer member variable hooked up to hold the user's selection, you might have a switch that takes an action based on that variable's value.

In switches like that example, you know that under normal circumstances, the code will never reach the default section in the switch. If the code ever should hit the default section, it would indicate either a bug in either the switch or the UI handling code. This is the kind of thing that asserts are designed to catch - conditions that should never occur if the code is working correctly.

I created this debugging macro, which I imaginitavely called DEFAULT_UNREACHABLE, that you can put at the end of your switches, to make sure that any bugs that are introduced which would cause execution to pass through the switch unhandled, are caught instead. The macro lets you know that something is wrong by generating an assertion failure. The macro has three parts:

  • Debug builds: Forces an assertion failure so MSVC will drop you in the debugger right at the spot where the bug showed up.
  • Release builds for VC 6 and later: Contains an <FONT COLOR="blue">__assume</FONT> statement as an optimization hint to the compiler. According to the VC docs, this reduces the size of the compiled code for the switch.
  • Release builds for VC 5 and earlier: Does nothing.

You may be wondering, "Why doesn't the release version do anything? Isn't the end result the same as without the macro?" That is indeed true, but remember that the debug version is the workhorse here. When you test your debug builds, you will catch and fix the bugs flagged by the macro, making sure that the code never gets to the default sections. That means that the release builds don't need any code in the default sections, because (say it with me) the code will never get there.

Without further ado, here is the code for the macro, and a sample showing how to use it.

<FONT COLOR="blue">#ifdef</FONT> _DEBUG
<FONT COLOR="blue">#define</FONT> DEFAULT_UNREACHABLE <FONT COLOR="blue">default</FONT>: ASSERT(0); <FONT COLOR="blue">break</FONT>
<FONT COLOR="blue">#elif</FONT> _MSC_VER >= 1200
<FONT COLOR="blue">#define</FONT> DEFAULT_UNREACHABLE <FONT COLOR="blue">default</FONT>: <FONT COLOR="blue">__assume</FONT>(0); <FONT COLOR="blue">break</FONT>
<FONT COLOR="blue">#else</FONT>
<FONT COLOR="blue">#define</FONT> DEFAULT_UNREACHABLE <FONT COLOR="blue">default</FONT>: <FONT COLOR="blue">break</FONT>
<FONT COLOR="blue">#endif</FONT>;

Sample usage: Imagine a dialog with radio buttons for selecting the day of the week. There is a variable m_nDay hooked up to the radio buttons.

void CMyDialog::OnOK()
{
    UpdateData();

    switch ( m_nDay )
        {
        case 0: case 6:
            // do something for the weekend...
        break;

        case 1: case 2: case 3:
            // something else for Mon-Wed...
        break;

        case 4: case 5:
            // and something else for Thu-Fri
        break;

        DEFAULT_UNREACHABLE;
        }</FONT>

I, as the author of the code, know that m_nDay should never contain a value other than 0 through 6, and if it ever does, it indicates a bug. So I put the

DEFAULT_UNREACHABLE
macro in the switch, and it will alert me if that situation ever happens.

As a final note, I should mention that the latest winnt.h in the SDK has a DEFAULT_UNREACHABLE macro, but it is not as good as the one here. The SDK version just reduces down to an <font color="blue">__assume</font> statement, and has no provision for aiding in debugging.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior) VMware
United States United States
Michael lives in sunny Mountain View, California. He started programming with an Apple //e in 4th grade, graduated from UCLA with a math degree in 1994, and immediately landed a job as a QA engineer at Symantec, working on the Norton AntiVirus team. He pretty much taught himself Windows and MFC programming, and in 1999 he designed and coded a new interface for Norton AntiVirus 2000.
Mike has been a a developer at Napster and at his own lil' startup, Zabersoft, a development company he co-founded with offices in Los Angeles and Odense, Denmark. Mike is now a senior engineer at VMware.

He also enjoys his hobbies of playing pinball, bike riding, photography, and Domion on Friday nights (current favorite combo: Village + double Pirate Ship). He would get his own snooker table too if they weren't so darn big! He is also sad that he's forgotten the languages he's studied: French, Mandarin Chinese, and Japanese.

Mike was a VC MVP from 2005 to 2009.

Comments and Discussions

 
GeneralOr to make things simple... Pin
PerFnurt9-Oct-02 1:20
PerFnurt9-Oct-02 1:20 
GeneralWrong philosophy Pin
2-Jan-02 20:56
suss2-Jan-02 20:56 
GeneralRe: Wrong philosophy Pin
CoderPond15-Dec-04 17:25
CoderPond15-Dec-04 17:25 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.