I recently heard about the Labels as Values extension to C/C++ in GCC and other compilers. I was thinking about how I’d use that to write a threaded interpreter (where a virtual machine program is defined by chaining together addresses of real machine code blocks).
Of course, I can only goto
a label from inside the function where the label is defined, but I still want to use the label values outside that scope; for instance, when I’m compiling or storing VM code rather than executing it. I am picturing an interpreter as something like this:
#include <stdio.h>
void interpret (void **prog) {
void **pc = prog;
goto **pc;
foo: printf("Foo"); goto nextword;
bar: printf("Bar"); goto nextword;
nextword:
if (*(++pc) != STOP) {
printf(" ");
goto **pc;
} else printf (".n");
stop: return;
}
// definition of VM instructions:
void *FOO=&&foo, *BAR=&&bar, *STOP=&&stop;
int main (int argc, char **argv) {
// a real interpreter would generate this from source code:
void *prog[] = {FOO, BAR, FOO, BAR, BAR, FOO, STOP};
interpret(prog);
return 0;
}
I.E., I want the label addresses as global constants. But the example above won’t compile, because the extension doesn’t allow labels-as-values outside of a function body, and labels in C have function scope anyway.
I could make the interpret()
function with a special “setup” mode, e.g. if I pass NULL
, it initialises the globals and returns immediately. I guess I could live with that, but it seems kludgey.
Several examples I’ve seen store the label addresses in a static array within the function and then pass the program as a list of integer indices into that array. But that adds an additional fetch operation to every VM instruction at runtime; doesn’t that run counter to the whole purpose of this extension?
Is there something I am missing? Or, if this is a feature request, is there a reason why something like my example couldn’t be implemented?