Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Emulating GCC's __builtin_unreachable?

I get a whole lot of warnings about switches that only partially covers the range of an enumeration switched over. Therefor, I would like to have a "default" for all those switches and put __builtin_unreachable (GCC builtin) in that case, so that the compiler know that case is not reachable.

However, I came to know that GCC4.3 does not support that builtin yet. Is there any good way to emulate that functionality? I thought about dereferencing a null pointer instead, but that may have other undesirable effects/warnings and such. Do you have any better idea?

like image 686
Johannes Schaub - litb Avatar asked May 17 '11 13:05

Johannes Schaub - litb


4 Answers

You can call an inline function declared _Noreturn to mark anything after that call as unreachable. The compiler is allowed to throw out any code after such a function. If the function itself is static (and does return), the compiler will usually also inline the function. Here is an example:

static _Noreturn void unreachable() {
    return; /* intentional */
}

/* ... */

foo();
bar(); /* should better not return */
unreachable();
baz(); /* compiler will know this is not reachable */

Notice that you invoke undefined behavior if a function marked _Noreturn indeed returns. Be sure that said function will never be called.

like image 137
fuz Avatar answered Nov 14 '22 23:11

fuz


Hmm, something like (since __builtin_unreachable() appeared in 4.5):


#define GCC_VERSION (__GNUC__ * 10000 \
                               + __GNUC_MINOR__ * 100 \
                               + __GNUC_PATCHLEVEL__)
#if GCC_VERSION >= 40500
#define my_unreachable()  __builtin_unreachable()
#else
#define my_unreachable() do { printf("Oh noes!!!111\n"); abort(); } while(0)
#endif

like image 29
janneb Avatar answered Nov 15 '22 00:11

janneb


Would abort (leaving a core dump) or throw (allowing for alternate data capture) accommodate your needs?

Do you really want to have switch statements that don't cover the full enumeration? I nearly always try to list all the possible cases (to no-op) with no default case so that gcc will warn me if new enumerations are added, as it may be required to handle them rather than letting it silently (during compile) fall into the default.

like image 4
Mark B Avatar answered Nov 15 '22 00:11

Mark B


keep it simple:

assert(false);

or, better yet:

#define UNREACHABLE (!"Unreachable code executed!")

assert(UNREACHABLE);
like image 3
CAFxX Avatar answered Nov 14 '22 23:11

CAFxX