regarding "goto" in C

M

M.B

Guys,
Need some of your opinion on an oft beaten track
We have an option of using "goto" in C language, but most testbooks
(even K&R) advice against use of it.
My personal experience was that goto sometimes makes program some more
cleaner and easy to understand and also quite useful (in error handling
cases).
So why goto is outlawed from civilized c programmers community.

is there any technical inefficiency in that.

Thank you
 
T

Thad Smith

M.B said:
Need some of your opinion on an oft beaten track
We have an option of using "goto" in C language, but most testbooks
(even K&R) advice against use of it.
My personal experience was that goto sometimes makes program some more
cleaner and easy to understand and also quite useful (in error handling
cases).
So why goto is outlawed from civilized c programmers community.

About 1968 or so Edsger Dijkstra wrote an article, published as a Letter
to the Editor in the ACM Communications magazine, titled Go To
Considered Harmful. He observed that unrestrained use of goto--what we
now refer to as "spaghetti code"--makes a program hard to understand and
therefore often has bugs. Shortly afterwards, there was much activity
to develop a method of programming, called structured programming, that
decomposed code into neat blocks, such as iteration, sequence, and
selection, such that no gotos were needed! It caught on as a way to
organize code.

The reason it is still with us is that as a general rule is that it
still helps to prevent the spaghetti code mess. Does it always produce
more understandable code? I don't think so, although it usually comes
close. In my opinion, it is a rule that should be understood and used
well before attempting to break it.
is there any technical inefficiency in that.

In general, there is some inefficiency with the elimination of goto.
In order to eliminate goto, you often have to implement additional
variables or flags to carry information from an inner loop to the
outside in order to stop intermediate processing, which is not needed if
you simply jump directly out of a loop. Also, there tends to be some
code duplication. Some people, such as I, cheat by returning from a
function more than one place in the body, a violation of the strict
structured approach.

At the machine level, there is almost always a jump or branch
instruction that performs a goto function.
 
K

Keith Thompson

M.B said:
Need some of your opinion on an oft beaten track
We have an option of using "goto" in C language, but most testbooks
(even K&R) advice against use of it.
My personal experience was that goto sometimes makes program some more
cleaner and easy to understand and also quite useful (in error handling
cases).
So why goto is outlawed from civilized c programmers community.

It's not "outlawed" unless you're working with a coding standard that
forbids it.

Goto statements can easily lead to "spaghetti code". The real problem
isn't the goto statement itself; it's the label. Whenever you see a
label in code, it's very difficult to tell how the program could have
gotten there. So-called "structured programming" intstead builds a
program structure from a set of higher-level constructs, such as
if/then/else, loops, switches, and so forth.

A program's structure often corresponds to something in the real-world
entity being modeled. An if statement corresponds to a decision. A
loop corresponds to doing something repeatedly. A goto statement
corresponds to ... well, to jumping from one point in the program to
another; it rarely matches anything in the real world (unless the
program is modeling a finite state machine).

Used with care, however, they can be useful, especially as a
substitute for a control structure that's missing from the language.
C doesn't have an exception handling mechanism, so gotos can be useful
for error handling (bailing out of a nested construct when something
goes wrong). C doesn't have a multi-level break statement, so gotos
can be useful for that.

A goto statement that branches backward, or that does something that
could have been done straightforwardly with a loop, is almost always a
bad idea.

The classic essay on the topic, from 1968, is Edsger W. Dijkstra's
"Go To Statement Considered Harmful", available at
<http://www.acm.org/classics/oct95/>.
 
T

tmp123

M.B said:
My personal experience was that goto sometimes makes program some more
cleaner and easy to understand and also quite useful (in error handling
cases).

Hi,

What you say has been experienced also by lots of programmers. Error
handling is sometimes easier to do with "goto".

We could say (saving a lot of details) that in order to skip the
contradiction
between "goto's are bad" and "goto's are good for error handling", the
concept of "exceptions" has been created.

Thus, I suggest you to review the usage of "try"/"catch"/... (forget my
sugestion if you know them).

Kind regards.
 
T

tmp123

Richard said:
tmp123 said:


They don't exist in C.


Yes, you have reason, I forget to remark it (a good reason to start in
C++).

However, I'm sure you known it is posible a workaround with a few
macros like:

#define TRY if(...(setjmp(...
#define CATCH else
#define RAISE logjmp(...

Kind regards.
 
R

Richard Heathfield

tmp123 said:
Yes, you have reason, I forget to remark it (a good reason to start in
C++).

No, it's not. It is a good thing to know how to write C++ programs, and also
a good thing to know how to write C programs, and it is an excellent thing
to know when to use which.
However, I'm sure you known it is posible a workaround with a few
macros like:

#define TRY if(...(setjmp(...
#define CATCH else
#define RAISE logjmp(...

I really wouldn't do that if I were you. There are subtleties to the
portable use of setjmp/longjmp which make it a non-trivial exercise.
 
C

Chuck F.

Keith said:
.... snip ...

A goto statement that branches backward, or that does something
that could have been done straightforwardly with a loop, is
almost always a bad idea.

The classic essay on the topic, from 1968, is Edsger W.
Dijkstra's "Go To Statement Considered Harmful", available at
<http://www.acm.org/classics/oct95/>.

See also:

<http://pplab.snu.ac.kr/courses/adv_p104/papers/p261-knuth.pdf>

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
 
C

Chuck F.

tmp123 said:
M.B wrote:
>

What you say has been experienced also by lots of programmers.
Error handling is sometimes easier to do with "goto".

We could say (saving a lot of details) that in order to skip the
contradiction between "goto's are bad" and "goto's are good for
error handling", the concept of "exceptions" has been created.

Thus, I suggest you to review the usage of "try"/"catch"/...
(forget my sugestion if you know them).

You have done a naughty thing. There is no "try/catch" in the C
language, thus they are not applicable here. In fact they are
off-topic. You might have been thinking of some other language
with a vague resemblance to C.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
 
J

John Bode

M.B said:
Guys,
Need some of your opinion on an oft beaten track
We have an option of using "goto" in C language, but most testbooks
(even K&R) advice against use of it.
My personal experience was that goto sometimes makes program some more
cleaner and easy to understand and also quite useful (in error handling
cases).
So why goto is outlawed from civilized c programmers community.

IME, there are cases where a goto is useful, but they are few and far
between. I have no problems with gotos provided some basic rules are
followed:

1. Branch forward only.
2. Never branch into the middle of another control structure (if, for,
while, etc.)
3. Don't use goto if another control structure can do the same job.
is there any technical inefficiency in that.

ISTR some verbiage in H&S that the presence of a goto can hinder some
compiler optimizations.
 
C

Chuck F.

John said:
.... snip ...

IME, there are cases where a goto is useful, but they are few and far
between. I have no problems with gotos provided some basic rules are
followed:

1. Branch forward only.

Counterexample:

preliminarysetup();
outer: while (condition1) {
dosumthing();
while (condition2) {
dosumthingelse();
if (condition3) goto outer;
domore();
}
dostillmore();
}

The goto cannot be replaced by break or continue, and even if it
could the goto is clearer.
2. Never branch into the middle of another control structure
(if, for, while, etc.)

See the Knuth paper (reference from me upthread) for a
counterexample. s/Never/Almost never/
3. Don't use goto if another control structure can do the same
job.

This one I can accept.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
 
E

Eric Sosman

Chuck said:
... snip ...



Counterexample:

preliminarysetup();
outer: while (condition1) {
dosumthing();
while (condition2) {
dosumthingelse();
if (condition3) goto outer;
domore();
}
dostillmore();
}

The goto cannot be replaced by break or continue, and even if it could
the goto is clearer.

Note that this can be trivially converted to a forward
branch by writing `outer: ;' just before the closing brace
of the outer loop. Note, too, that this conversion would be
necessary, not just possible, if the outer loop were a `for'
or a `do...while'.
 
R

Red Cent

Two things I think need pointed out here.

1) As mentioned earlier in this thread, goto does NOT necessarily lead
to poor programming. If used with care, goto maybe a good choice, but
there is always an alternative. Whether it's a function call, a case
switch. All of these can be good alternatives BUT they can be abused
as well.

At least with a function call you know where and when that piece of
code will execute. But with labelled lines for goto purposes, it's
difficult to tell when it's being called, and when those lines just run
because of the order of execution.

2) Today's goto? #define!

I have often seen (and not just in purposely obfuscated code)
ridiculous define statements due to laziness. These problems often
disappear once people begin working together in a group, or review each
other's source code.
 
K

Keith Thompson

John Bode said:
IME, there are cases where a goto is useful, but they are few and far
between. I have no problems with gotos provided some basic rules are
followed:

1. Branch forward only.
2. Never branch into the middle of another control structure (if, for,
while, etc.)
3. Don't use goto if another control structure can do the same job.

Your rule 3 would eliminate goto statements altogether. There's a
well known theorem that any program using gotos can be transformed
into an equivalent program using only a particular small set of
structured control constructs (possibly with some extra flag
variables).

I'd amend your rule 3 to

3. Use goto only if it's (significantly) cleaner than any of the
equivalent alternatives.

and add:

4. If forced by circumstances to use a goto, curse under my breath
about the lack of a cleaner alternative in the language.

I can think of 3 cases where a goto is justified in C: an explicit
finite state machine, where a goto actually models something in the
problem domain (this could also be implemented as a switch statement
in a loop with an explicit state variable); error handling (due to the
lack of a decent exception handling mechanism); and breaking out of a
nested loop (due to C's regrettable lack of multi-level break).

The latter two could also be implemented by wrapping part of the code
in a small (perhaps inline) function, and using a return statement to
break out of it, but that's not necessarily an improvement. In
particular, it causes problems if an inner loop accesses variables
declared in outer scopes.
 
M

Marco

M.B said:
So why goto is outlawed from civilized c programmers community.

several coding standard/style books

"Enough Rope to Shoot Yourself In the Foot"
" The Elements of C Programming Style"

suggest that a forward goto from nested loops is perfectly acceptable

they have examples similar to

while( condtion1 )
{
while( condtion2 )
{
if (something_bad)
goto leave;
...
}
}
leave:
...

I have used this in practice once or twice.
 
C

Chuck F.

Eric said:
Note that this can be trivially converted to a forward branch by
writing `outer: ;' just before the closing brace of the outer
loop. Note, too, that this conversion would be necessary, not
just possible, if the outer loop were a `for' or a `do...while'. >

I submit that coding a jump forward to execute a jump backward is
code obfuscation. As further evidence I cite the need for the
extraneous semicolon in this case.

For the do-while I agree, but with a for-loop I also claim that the
wrong loop is in use. I generally do not approve of using the for
as a generic loop construct when other constructs have the same effect.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
 
A

August Karlstrom

Keith Thompson wrote:
[snip]
I can think of 3 cases where a goto is justified in C: an explicit
finite state machine, where a goto actually models something in the
problem domain (this could also be implemented as a switch statement
in a loop with an explicit state variable); error handling (due to the
lack of a decent exception handling mechanism); and breaking out of a
nested loop (due to C's regrettable lack of multi-level break).

The latter two could also be implemented by wrapping part of the code
in a small (perhaps inline) function, and using a return statement to
break out of it, but that's not necessarily an improvement. In
particular, it causes problems if an inner loop accesses variables
declared in outer scopes.

That's because C doesn't support local subroutines. If your language
does, it's a neat solution.


August
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top