I'm trying to make a macro-based jump table in C.
Here's some example code:
#include "stdio.h"
#define GOTO(X) static void* caseArg[] = {&&I0, &&R0, &&S0, &&F0, &&G0, &&H0}; \
goto *caseArg[X];
#define FINISH() goto caseEnd;
int main(int argc, char** argv) {
GOTO(1);
I0: printf("in I0\n"); FINISH();
R0: printf("in R0\n"); FINISH();
S0: printf("in R0\n"); FINISH();
F0: printf("in R0\n"); FINISH();
G0: printf("in R0\n"); FINISH();
H0: printf("in R0\n"); FINISH();
caseEnd:;
}
The possible labels (I0, R0, etc) have to be the same.
The problem is: I want to be able to use the same macro in different scoped parts of the same source file. However, the compiler complains that the labels are defined.
What I want to achieve:
int main(int argc, char** argv) {
{ // scope 1
GOTO(1);
I0: printf("in I0\n"); FINISH();
R0: printf("in R0\n"); FINISH();
S0: printf("in R0\n"); FINISH();
F0: printf("in R0\n"); FINISH();
G0: printf("in R0\n"); FINISH();
H0: printf("in R0\n"); FINISH();
caseEnd:;
}
{ // scope 2
GOTO(4);
I0: printf("in I0\n"); FINISH();
R0: printf("in R0\n"); FINISH();
S0: printf("in R0\n"); FINISH();
F0: printf("in R0\n"); FINISH();
G0: printf("in R0\n"); FINISH();
H0: printf("in R0\n"); FINISH();
caseEnd:;
}
}
Any ideas? Any possible workaround?

You need the
__label__extension (at least in gcc, clang, and tinycc), which allows you to scope labels to a block.The labels need to be declared at the very start of a block with
(Contiguous
__label__ I0; __label__ R0; ...or a mix of the two forms works as well.).Unless declared scope-local with
__label__, C labels are scoped to their enclosing function.Your example with
__label__:https://gcc.godbolt.org/z/63YSkG
In this particular case, such a local-label based jumptable seems to buy little over a plain old
switch.