Herbert said:
You're right that my example is not the best. But in the short time I
found nothing that I were able to use to make from a nonsense a real
good design. For a blind hack of code that makes as such no sense it
was the best to show up other code without sense but avoiding goto.
Real design starts at much higher level and will avoid some constructs
before there is a chance to write a single statement.
I don't doubt it's possible to call some approach to design "real design"
and coincidentally have this approach avoid all cases where goto could come
in handy.
Not that it's easy, mind you. If high-level "real design" impacts how code
is written at the lowest level, there is something suspicious about it.
!! is a possibility to save typing (and mistyping, e.g. like = instead
of ==). True, yes I do never take consideration of beginners in
learning C because one has to learn the language by using it.
I'm not a beginner and I do know perfectly what !! means. Knowing what it
means and wanting to use it are two different things (as you know, of
course, through avoiding goto.
The = vs. == thing is indeed another wart of C best avoided, but this at
least is something even the beginners quickly grow wise to. There's not
enough code out there using the !! trick to make it as readable. You can
parse it, but it takes time. How much time code takes to *type* is all but
insignificant (I'm sure managers will tell you otherwise, but most of those
managers couldn't program if their lives depended on it, let alone judge
coding techniques.)
Yes, I don't like empty lines whenever there is a chance to avoid one,
except an empty line can stand for self declaring documentation saying
there starts a new logical block of execution. Yes, I avoid {}
whenever possible because that gives up to 2 more lines on the same
screen page.
Well, this is another one of those holy war things we'd best not touch and
chalk up to personal preference. Those things probably make a difference one
way or another, but not enough to quibble about.
But for that my editor knows how to indent right and it will prove the
matching of braces every time I ask it for. True, this all is at least
a question of style but avoiding goto and longjump is never. You would
know that when you have written one singe project that has not only to
be failsave but has to save human live in any condition and not only
some money.
Ooh, here you go making assumptions, and we all know how dangerous that is.
You're in luck, though: I'm not going to tell you I wrote the control
program for a nuclear reactor or an X-ray scanner and used goto and
longjmp() to good effect. I wouldn't turn this into a "my application field
is more sensitive to failure than yours" debate, though; this tends to be
unproductive. Some applications that saved "some money" arguably had plenty
of impact on the quality and possibly quantity of human life, too.
Even without the benefit of this no doubt insightful experience, your
assertion is mere bluster, since you're not going to prove that the use of
goto was what condemned such a project in the past. It is an appeal to
emotion that boils down to "goto makes your project bad, and in your really
important project it's a liability".
What next? "goto kills"? I'm sure it has. So have floating-point
calculations and exceptions (in other languages). In all of these cases it
is dubious to propose the features themselves were wrong. Misapplied, yes.
Easy to misapply, certainly. Never appropriate, not necessarily.
What is true is that goto (and longjmp() even more so) are hard to use
*appropriately*. This is why goto should be avoided: if you don't know why
you're using goto and not some other control structure, you're not using it
right and should stop. Write something you can control. Better, write
something that is obvious not just to you, but to anyone of slightly less
capacity than yourself. (It is useless to write code for programmers vastly
worse than yourself, since they cannot modify what they do not understand
anyway; it is likewise useless to try and be smarter than you actually are
on a bad day, which is a much more common failing.)
Programmers do not how to use goto properly either because they've *never*
been told not to use it, or because they've *always* been told not to use
it. Yes, you can shoot yourself in the foot with goto, no question about it.
Then again, you can shoot yourself in the foot with a lot of things in C.
None of this can serve as a blanket condemnation. The pitfalls of goto are
well known, and all the arguments for and against are, too. Those who are
not familiar with them should stick with "never use goto", since it makes
the world a better place for all of us. I would be the last one to advocate
changing this happy status quo.
goto has its uses. Anyone who denies this is calling Donald Knuth wrong.
Unrestricted use of goto is harmful. Anyone who denies this is calling
Edsger Dijkstra wrong. I wouldn't take either of those men on lightly
without some very good arguments, because they usually have them handy.
I'd like to close this debate with an important remark: I can count the
number of times I've used goto in applications on the fingers of one hand,
quite unlike the number of programs I've written, for which no appendages
suffice (they would if I counted in binary, though). The count for longjmp()
stands at zero.
Why? Because goto was not the appropriate solution to the problem in almost
every case. In those cases where I used it, it was. Equivalent code not
using goto of course existed, but it was less elegant and less readable.
There aren't many legitimate uses of goto -- but where they are, it is
fanaticalism to say that they, too, should be abolished because they raise
the spectre of wrongful application. It's likewise silly to say "but you can
do that without goto". Of course. Then I can say "but you can do that
without while". It doesn't really advance things.
S.