learner0000 learner0000 - 3 months ago 10
C++ Question

Why use a pre-processor directive for a 'case' statement?

I was browsing through the SpiderMonkey engine source and saw some code in the interpreter that intrigued me.

// Portable switch-based dispatch.
# define INTERPRETER_LOOP() the_switch: switch (switchOp)
# define CASE(OP) case OP:
# define DEFAULT() default:


(source: https://dxr.mozilla.org/mozilla-b2g44_v2_5/source/js/src/vm/Interpreter.cpp#1579)

Is there any non-stylistic benefit for defining something like
case OP:
as
CASE(OP)
?

Answer

Look up half a screen:

#if (defined(__GNUC__) ||                                                         \
     (__IBMC__ >= 700 && defined __IBM_COMPUTED_GOTO) ||                      \
     __SUNPRO_C >= 0x570)
// Non-standard but faster indirect-goto-based dispatch.
# define INTERPRETER_LOOP()
# define CASE(OP)                 label_##OP:
// ... <snip>
#else
// Portable switch-based dispatch.
# define INTERPRETER_LOOP()       the_switch: switch (switchOp)
# define CASE(OP)                 case OP:
// ... <snip>
#endif

GCC and some other compilers support "computed goto", which is faster than a loop-switch for an interpreter loop, but is non-standard and hence non-portable.

If the compiler supports computed goto, the first branch of this #if defines INTERPRETER_LOOP, CASE(OP) etc. to use computed goto; otherwise, the #else branch defines them in terms of standard facilities.

Comments