Freigeben über


Breaking code on purpose

Breaking code is useful. When we run into an impossible situation, it's better to fail early and predictably, especially in a debug build, where the users of which are likely to notice and kindly sent a bug report. (Most of the time, these bug reports will even lack profanity.) On the other hand, in production code, it's sometimes best to muddle through as best we can in these situations. A few months ago, a colleague of mine came up with a nifty way to mark "this can't happen" cases:

 
BOOL
FrobWidget (
    Widget* WidgetToFrob
    )
{
    switch (WidgetToFrob->Color) {
        case WIDGET_COLOR_BLUE:
            assert (!"Blue widgets cannot be frobbed");
            return FALSE;
        ....
    }

    return TRUE;
}

Doing it that way is clear, concise, and prettier than assert (false) and abort. The string literal won't be included in binaries built without assertions.

Granted, we sometimes need to break code in production builds too. abort () is the traditional way to do it, but DbgBreakPoint is a better choice. If no debugger is attached, the current process will exit unexpectedly, but if a debugger is attached, the debugger can step through a DbgBreakPoint call. Unlike __debugbreak, DbgBreakPoint isn't a compiler intrinsic, so it'll do the right thing on any compiler. Unlike DebugBreak, DbgBreakPoint will compile down to a single instruction when the compiler supports the proper intrinsic, making it easier to NOP out in a debugger. DbgBreakPoint is the best choice for breaking code on purpose.