A
Adam
To explain why I am trying to do a non-C thing in C, I am writing a
translator for a toy language targeting C.
To do this I need a way to perform assigned gotos, by which I mean I
have a number of labels LABEL_0, LABEL_0, .. LABEL_N, and wish to be
able to take an int k and do goto LABEL_k. ( I can't use function
pointers as they would be called recursively, and one soon runs out of
stack space.)
In GCC and similar, I can use the && operator to take the address of
labels, and that works fine. However I want a second solution for
those compilers that do not support this extension.
I would also like that performing the goto takes constant time, and
does not depend on the number of labels, it is to be expected that
there will be many labels.
My current solution uses setjmp/longjmp, it creates an array jmp_buf
jump_table[ size], and then initialises it by
LABEL_k : if(!setjmp( jump_table[k] ) { goto LABEL_(k+1) }
I can then go to LABEL_k by calling longjump(jump_table[k])
I have the following questions:
Is this approach correct? Not having used setjmp/longjmp before, I
want to check I'm not making some mistake.
I need that the value of one particular variable is not changed by the
longjmp, and so it can not be stored in a register. I can ensure this
by declaring it volatile, yes?
Finally, and most importantly, is there a better way to do this?
translator for a toy language targeting C.
To do this I need a way to perform assigned gotos, by which I mean I
have a number of labels LABEL_0, LABEL_0, .. LABEL_N, and wish to be
able to take an int k and do goto LABEL_k. ( I can't use function
pointers as they would be called recursively, and one soon runs out of
stack space.)
In GCC and similar, I can use the && operator to take the address of
labels, and that works fine. However I want a second solution for
those compilers that do not support this extension.
I would also like that performing the goto takes constant time, and
does not depend on the number of labels, it is to be expected that
there will be many labels.
My current solution uses setjmp/longjmp, it creates an array jmp_buf
jump_table[ size], and then initialises it by
LABEL_k : if(!setjmp( jump_table[k] ) { goto LABEL_(k+1) }
I can then go to LABEL_k by calling longjump(jump_table[k])
I have the following questions:
Is this approach correct? Not having used setjmp/longjmp before, I
want to check I'm not making some mistake.
I need that the value of one particular variable is not changed by the
longjmp, and so it can not be stored in a register. I can ensure this
by declaring it volatile, yes?
Finally, and most importantly, is there a better way to do this?