While making everthing with goto's is easy (as evidenced by f.ex. IL), I was wondering if it is also possible to eliminate all goto statements with higher level expressions and statements - say - using everything that's supported in Java.
Or if you like: what I'm looking for is 'rewrite rules' that will always work, regardless of the way the goto is created.
It's mostly intended as a theoretical question, purely as interest; not as a good/bad practices.
The obvious solution that I've thought about is to use something like this:
while (true)
{
switch (state) {
case [label]: // here's where all your goto's will be
state = [label];
continue;
default:
// here's the rest of the program.
}
}
While this will probably work and does fits my 'formal' question, I don't like my solution a single bit. For one, it's dead ugly and for two, it basically wraps the goto into a switch that does exactly the same as a goto would do.
So, is there a better solution?
Update 1
Since a lot of people seem to think the question is 'too broad', I'm going to elaborate a bit more... the reason I mentioned Java is because Java doesn't have a 'goto' statement. As one of my hobby projects, I was attempting to transform C# code into Java, which is proving to be quite challenging (partly because of this limitation in Java).
That got me thinking. If you have f.ex. the implementation of the 'remove' method in Open addressing (see: http://en.wikipedia.org/wiki/Open_addressing - note 1), it's quite convenient to have the 'goto' in the exceptional case, although in this particular case you could rewrite it by introducing a 'state' variable. Note that this is just one example, I've implemented code generators for continuations, which produce tons and tons of goto's when you're attempting to decompile them.
I'm also not sure if rewriting in this matter will always eliminate the 'goto' statement and if it is allowed in every case. While I'm not looking for a formal 'proof', some evidence that elimination is possible in this matter would be great.
So about the 'broadness', I challenge all the people that think there are 'too many answers' or 'many ways to rewrite a goto' to provide an algorithm or an approach to rewriting the general case please, since the only answer I found so far is the one I've posted.
goto
is a hack that can improve performance in edge cases (from a practical perspective: tokenizers, IL execution engines, and kernels). It's never unreplaceable in any case. – Marniwhile
,for
and other looping constructs internally uses goto? So you want to avoid using loops? Trying to avoid switch statement makes no sense. Well, you could refactor the switch to use polymorphism but there should be atleast one. – UnwishC#
, then I suppose you have a point - but that doesn't get us closer to a solution. – Weltongoto
in itself is not evil. It's the lack of transparency of its operation and the control flow that is considered 'better to avoid'. Everywhile
could also be written in afor
, but neither of them has the intrinsic capability to generate true spaghetti, that's why both of them exist as a convenience. The flexibility ofgoto
also implies that formalization is going to be very hard, if not impossible, as it's essentially an encapsulation of an assembly-level construct. I doubt you're going to fully succeed there :) – Marni