Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > when GOTO makes sense.

Reply
Thread Tools

when GOTO makes sense.

 
 
Debashish Chakravarty
Guest
Posts: n/a
 
      11-29-2003
K&R pg.66 describes two situations when using goto makes sense. Has
anyone here come across situations where using goto provided the most
elegant solution.

--
http://www.kashmiri-pandit.org/atrocities/index.html



 
Reply With Quote
 
 
 
 
Mark F. Haigh
Guest
Posts: n/a
 
      11-29-2003
Debashish Chakravarty wrote:

> K&R pg.66 describes two situations when using goto makes sense. Has
> anyone here come across situations where using goto provided the most
> elegant solution.
>


Yes. Sometimes when...

1. There is code with a lot of resource allocation and/or semaphores
being held and...

2. There are many potential points of failure and...

3. The resources need to be freed in a very precise order on failure...

.... goto usage can be the most elegant solution.


Because of #1 it's very important to prevent resource leaks and/or
deadlocks. #2 makes it problematic and error prone (for maintenence
programmers) to do:

if(error_condition) {
free(a);
free(b);
unlock(c);
unlock(d);
free(e);
return -1;
}

at every point where a failure may occur (there may be 10 of them, and
each may be subtly different). It may be better to have something like:
(again, only a contrived example, assuming a, b, c, e are initialize
to NULL, etc)


if(error_condition)
goto err;

/*...*/

err:
/* Order important !! */
if(a) free(a);
if(b) free(b);
if(c) free(c);
unlock(c); /* must unlock c before d */
unlock(d); /* must unlock d before free(e) */
if(e) free(e);
return -1;
}


Mark F. Haigh
http://www.velocityreviews.com/forums/(E-Mail Removed)



 
Reply With Quote
 
 
 
 
Paul Hsieh
Guest
Posts: n/a
 
      11-29-2003
Debashish Chakravarty <(E-Mail Removed)> wrote:
> K&R pg.66 describes two situations when using goto makes sense. Has
> anyone here come across situations where using goto provided the most
> elegant solution.


The classic case is breaking out of a nested loop from the inside.
While people who hate goto for some reason despise such things and
prefer having extra if-checks to account such a condition, its slower,
and just makes your code more complicated.

But another interesting case is with state machines. While the
classic implementation of a state matchine is to simply put a switch
statement inside of a while (1) { ... } loop, this has a drawback of
requiring the switch statement to be execute on every state change (on
modern processors this is much slower than direct gotos.) But as an
alternative, one could simply have one switch statement and rather
than breaks at the end of each case block, simply have gotos to the
blocks that represent the state transition. You have to have labels
that are redundant with the case ...: statements, however this
solution is much faster, and doesn't require that you maintain a state
variable (since the state itself would be redundant with the case
clause that was being executed at any one time) for all states (just
entry and exit of the state machine.)

Finally sometimes its best, for performance reasons to start a loop in
the middle of the body of the loop rather than a start. So you have a
goto just before your do {...} while or for() loop to enter in the
middle of it.

These are probably the most interesting marginal cases where using
goto is the best solution in the C language. The problem is that
there are many other uses of goto which are really really bad. So
much so that people have railed against its usage, and will actually
choose not to do so in any situation. They will lose performance
and/or make their code complicated in all of the above cases. So this
*should* make a good case for improving improving the language so that
these operations can be done *without* goto (for example <break n;> to
jump out of n nested blocks, and <continue case ___;> to jump to a
case within the nearest enclosing switch scope.) However, I don't
know if the C standards committee is open to suggestions such as
these.

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/
 
Reply With Quote
 
Michael B.
Guest
Posts: n/a
 
      11-30-2003
On Sat, 29 Nov 2003 06:00:40 -0800, Paul Hsieh wrote:

>
> But another interesting case is with state machines. While the
> classic implementation of a state matchine is to simply put a switch
> statement inside of a while (1) { ... } loop, this has a drawback of
> requiring the switch statement to be execute on every state change (on
> modern processors this is much slower than direct gotos.) But as an
> alternative, one could simply have one switch statement and rather
> than breaks at the end of each case block, simply have gotos to the
> blocks that represent the state transition. You have to have labels
> that are redundant with the case ...: statements, however this
> solution is much faster, and doesn't require that you maintain a state
> variable (since the state itself would be redundant with the case
> clause that was being executed at any one time) for all states (just
> entry and exit of the state machine.)
>


Hmm, I've always implemented state machines with function pointers, like
so:
.... in the header:
typedef void * (*state) (int);
.... in main.c:
while (ch = getnewinput()) {
current = (state)(*current)(ch);
}
}
.... example state: ( this is a very simple DFA )
void *
green (int input) {
switch (input) {
case 'A':
printf("LIGHTS OFF\n");
return &other;
break;
case 'B':
printf("LIGHTS OFF\n");
return &initial;
break;
}
}

Of course, casting function pointers to void and back can lead to
undefined behavior on certain architectures (though I've verified that
this code works on x86 and PPC). But doesn't this seem like a better
solution (and definitely more functional, seeing as it basically emulates
the workings of a functional language), than using gotos?

--
Mike's Patented Blocklist; compile with gcc:

i=0;o(a){printf("%u",i>>8*a&255);if(a){printf(".") ;o(--a);}}
main(){do{o(3);puts("");}while(++i);}

 
Reply With Quote
 
Christian Bau
Guest
Posts: n/a
 
      11-30-2003
In article <(E-Mail Removed)>,
"Michael B." <(E-Mail Removed)> wrote:

> Of course, casting function pointers to void and back can lead to
> undefined behavior on certain architectures (though I've verified that
> this code works on x86 and PPC). But doesn't this seem like a better
> solution (and definitely more functional, seeing as it basically emulates
> the workings of a functional language), than using gotos?


It leads to undefined behavior, that's it. So that makes it in the eyes
of most people a very bad solution, definitely worse than using goto.

It also mixes up "states" and "implementation of code to handle the
action in a given state". Each of your functions doesn't return a state,
it returns a pointer to the code to be executed in that state.

And it adds significantly to the number of lines of code to be written.
In most state machines, the code for each state is quite trivial, so
adding a few lines for every state adds significantly to the lines of
code.
 
Reply With Quote
 
James Dow Allen
Guest
Posts: n/a
 
      12-01-2003
"Mark F. Haigh" <(E-Mail Removed)> wrote in message news:<zFUxb.61536$(E-Mail Removed) .com>...
> Debashish Chakravarty wrote:
> > anyone here come across situations where using goto provided the most
> > elegant solution.

> Yes. Sometimes when...
> 2. There are many potential points of failure and...
> 3. The resources need to be freed in a very precise order on failure...


These gotos may sometimes be avoided by replacing
if (! step7())
goto backout7;
if (! step8())
goto backout8;
...
with
if (step7()) {
if (step8()) {
...
}
}
but the cure may be worse than the disease
if there are many levels of nesting.

Another frequent case where goto is better than the alternative is
for (Search; unfinished {
for (Subsearch; unfinished {
if (WE_WON) {
celebrate();
goto persevere;
}
}
}
lament();
persevere: ;

(Even when loops are not nested, a ``break'' is not quite
enough to avoid this ``goto.'')

I use very few gotos in *final* code, but when cranking out
fresh code, I sometimes write ``goto start_over'' and then decide
later, when I see the full logic, whether to rewrite the loop as
``do'', ``while'' or ``for.'' (In other words, the goto-less
version will be more *readable*, but the *goto* is more *writable*.)

Finally, let me mention my Favorite Goto (tm):
http://freepages.genealogy.rootsweb....ech/dbldum.htm

If one needs to make major changes to the Favorite Goto program,
getting rid of the goto might be the first step, but as is,
it possesses, IMO, a beautiful elegance no non-GOTO version
will have. Can you construct a goto-less equivalent that is
in the same ballpark for speed and readability?

(I have posted the Favorite Goto before on Usenet, receiving
some suggestions which made no sense. Please code, compile and
test your version before sending it to me.)

James
 
Reply With Quote
 
Dan Pop
Guest
Posts: n/a
 
      12-01-2003
In <(E-Mail Removed)> Debashish Chakravarty <(E-Mail Removed)> writes:

>K&R pg.66 describes two situations when using goto makes sense. Has
>anyone here come across situations where using goto provided the most
>elegant solution.


'Elegant' is in the eye of the beholder. I prefer to speak in terms of
readable code. The code readability decreases exponentially when the
number of nested control structures increases linearly. If a goto can
avoid an additional nesting level, than that goto is probably a "good"
goto. Of course, this is not the only technique for minimising the number
of nested control structures in a function, but one shouldn't
automatically discard it on religious grounds.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: (E-Mail Removed)
 
Reply With Quote
 
Ed Morton
Guest
Posts: n/a
 
      12-01-2003


James Dow Allen wrote:

<snip>
> Finally, let me mention my Favorite Goto (tm):
> http://freepages.genealogy.rootsweb....ech/dbldum.htm
>
> If one needs to make major changes to the Favorite Goto program,
> getting rid of the goto might be the first step, but as is,
> it possesses, IMO, a beautiful elegance no non-GOTO version
> will have. Can you construct a goto-less equivalent that is
> in the same ballpark for speed and readability?


This MAY (or may not) be the most efficient piece of code on the planet,
but this has to be some of the worst code I've ever seen for
readability. In particular, jumping back and forth between the bodies of
2 separate pairs of nested "for" loops using "goto"s is horrible, and
then having compound conditions like this in a loop:

for (tnum = won = success = 0;
success ? ++won < need : won + ohsize >= need + tnum;
tnum++, P++, success = IS_CONT(pwin)) {

is just ridiculuous too.

By the way, the program hangs on the second sample input provided on the
web site. I would debug it, but I don't want to take the time to
understand it . Ditto for providing a non-goto alternative.

I'm not 100% against gotos, I've just never seen code that uses gotos
that I personally find more readable than the equivalent without gotos.
I recently wrote a short (200 lines or so) program using gotos just to
see if I could learn to appreciate the benefits wrt error-handling, but
once the error-handling became even moderatly complex (i.e. realisitc!)
the initial simplicity afforded by the gotos fell away. I looked at your
code hoping to learn a good way to use goto for readability.

Ed.

 
Reply With Quote
 
The Real OS/2 Guy
Guest
Posts: n/a
 
      12-01-2003
On Mon, 1 Dec 2003 05:13:10 UTC, (E-Mail Removed) (James Dow
Allen) wrote:

> I use very few gotos in *final* code, but when cranking out
> fresh code, I sometimes write ``goto start_over'' and then decide
> later, when I see the full logic, whether to rewrite the loop as
> ``do'', ``while'' or ``for.'' (In other words, the goto-less
> version will be more *readable*, but the *goto* is more *writable*.)


> Finally, let me mention my Favorite Goto (tm):
> http://freepages.genealogy.rootsweb....ech/dbldum.htm


Looks more obscure than needed. A better structure is required.

Use functions to encapsulate details from the flow.
Using the the same functions would remove any need for goto as side
effect.
You've written some loops looking exactly identical. Buildng fuctions
would remove the details from the flow and lets them reused.

Programming starts with design, not hacking.
A well designed program has not a single function but many of them,
each not longer than about 50 lines, doing one specific task. Not
more, not less.

A task gets splitted in What is to do and how is it done. This makes
debugging more easy, helps to understund the flow and is at least more
readable as such a hack as you'd produced.

> If one needs to make major changes to the Favorite Goto program,
> getting rid of the goto might be the first step, but as is,
> it possesses, IMO, a beautiful elegance no non-GOTO version
> will have. Can you construct a goto-less equivalent that is
> in the same ballpark for speed and readability?


A side effect would be that there is no goto in the whole program.
That is because the need of goto gets superflous by design.

--
Tschau/Bye
Herbert

To buy eComStation 1.1 in germany visit http://www.pc-rosenau.de

 
Reply With Quote
 
Alan Balmer
Guest
Posts: n/a
 
      12-01-2003
On Fri, 28 Nov 2003 22:08:10 -0500, Debashish Chakravarty
<(E-Mail Removed)> wrote:

>K&R pg.66 describes two situations when using goto makes sense. Has
>anyone here come across situations where using goto provided the most
>elegant solution.


Yes.

--
Al Balmer
Balmer Consulting
(E-Mail Removed)
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
VHDL Goto statement ? Skybuck Flying VHDL 9 08-26-2005 01:46 PM
Re: VHDL Goto statement ? Skybuck Flying VHDL 0 08-08-2005 03:21 AM
where does Console.WriteLine() goto in a web app? Flip ASP .Net 1 04-14-2005 08:01 PM
where does Console.WriteLine() goto? Flip ASP .Net 6 11-18-2004 06:05 PM
goto statement is recommened in systemc? youngsun park VHDL 2 11-18-2003 03:47 PM



Advertisments