I know everyone hates gotos. In my code, for reasons I have considered and am comfortable with, they provide an effective solution (ie I'm not looking for "don't do that" as an answer, I understand your reservations, and understand why I am using them anyway).
So far they have been fantastic, but I want to expand the functionality in such a way that requires me to essentially be able to store pointers to the labels, then go to them later.
If this code worked, it would represent the type of functionality that I need. But it doesn't work, and 30 min of googling hasn't revealed anything. Does anyone have any ideas?
int main (void)
{
int i=1;
void* the_label_pointer;
the_label:
the_label_pointer = &the_label;
if( i-- )
goto *the_label_pointer;
return 0;
}
You can assign label to variable using &&. Here is your modified code.
I know the feeling then everybody says it shouldn't be done; it just has to be done. Here's how to do it:
The label dereferencing operator && will only work with gcc. And obviously the jumpto assembly macro needs to be implemented specifically for each processor (this one works with both 32 and 64 bit x86). Also keep in mind that there is no guarantee that the state of the stack is the same at two different points in the same function. And at least with some optimization turned on it's possible that the compiler assumes some registers to contain some value at the point after the label. These kind of things can easily get screwed up then doing crazy shit the compiler doesn't expect. Be sure to proof read the compiled code.
The
switch ... case
statement is essentially a computedgoto
. A good example of how it works is the bizarre hack known as Duff's Device:You can't do a
goto
from an arbitrary location using this technique, but you can wrap your entire function in aswitch
statement based on a variable, then set that variable indicating where you want to go, andgoto
that switch statement.Of course, if you do this a lot, you'd want to write some macros to wrap it.
This technique, along with some convenience macros, can even be used to implement coroutines in C.
Use function pointers and a while loop. Don't make a piece of code someone else will have to regret fixing for you.
I presume you're trying to change the address of the label somehow externally. Function pointers will work.
You can do something similar with setjmp/longjmp.