Does “default” switch case disturb jump table optimization?

你离开我真会死。 提交于 2019-12-05 02:24:05

If your compiler is MSVC, you can use __assume intrinsic : http://msdn.microsoft.com/en-us/library/1b3fsfxw(v=VS.80).aspx

At least with the compilers I've looked at, the answer is generally no. Most of them will compile a switch statement like this to code roughly equivalent to:

if (mode < modeA || mode > modeLast) {
    assert(0 && "Unknown mode!");
    return ADummyValue();
}
switch(mode) { 
    case modeA: ...;
    case modeB: ...;
    case modeC: ...;
    // ...
    case modeLast: ...;
}

if you're using "default" (ha!) <assert.h>, the definition's tied to the NDEBUG macro anyway, so maybe just

    case nevermind:
#if !defined(NDEBUG)
    default:
        assert("can" && !"happen");
#endif
    }

I only see 1 solution in case the optimization actually is disturbed: the infamous "#ifndef NDEBUG" round the default case. Not the nicest trick, but clear in this situation.

BTW: did you already have a look what your compiler does with and without the default case?

If you have a state that should never be reached, then you should kill the program, because it just reached an unexpected state, even in the release mode (you might just be more diplomatic and actually save users data and do all that other nice stuff before going down).

And please don't obsess over micro optimizations unless you actually have measured (using a profiler) that you need them.

The best way to handle this is not to disable the assert. That way you can also keep an eye on possible bugs. Sometimes it is better for the application to crash with a good message explaining what exactly happened, then to continue working.

Use compiler extensions:

// assume.hpp
#pragma once

#if defined _MSC_VER
#define MY_ASSUME(e) (__assume(e), (e) ? void() : void())
#elif defined __GNUC__
#define MY_ASSUME(e) ((e) ? void() : __builtin_unreachable())
#else   // defined __GNUC__
#error unknown compiler
#endif  // defined __GNUC__

-

// assert.hpp
#include <cassert>
#include "assume.hpp"

#undef MY_ASSERT
#ifdef NDEBUG
#define MY_ASSERT MY_ASSUME
#else   // NDEBUG
#define MY_ASSERT assert
#endif  // NDEBUG
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!