Chris said:
But the same is true about blanket forbidding of goto.
I think one problem a lot of people have with it, is seeing it being
used/abused so often. Yes this should not mean we forbid it, but its use
should be very limited.
I had the great 'pleasure' to have to add a new feature to an existing
product, in which the original developer could not see an easy way out
of a 2 tier nested for loop with several If conditions inside. So they
used goto BAD_BOY:
He knew it was rubbish code, but time pressure meant he wanted something
out quickly. This code was supposed to remain in existence for a few
days until he could make it better. He even left a comment saying as much.
It lived for almost 2 years before finally being refactored away in
order to add functionality.
Unclear programming is always bad, no language structure is inherrently bad
(well, OK, Intercal!) it's how you use it.
For clarity when appropriate.
void func(...)
{
for (...)
{
for (...)
{
for (...)
{
/* do stuff */
if (something_wrong)
goto cleanup;
/* do more stuff */
if (something_wrong)
goto cleanup;
}
}
}
cleanup:
/* do cleanup stuff */
}
It's a lot clearer than using flags to do it, and return isn't
appropriate because the 'cleanup' code would need to be duplicated which
is a maintenabce risk.
The problem I have with this type of code structure though, is that
whilst I can see on the screen the 3 nested for loops, the two If
conditions, the Do stuff AND finally the cleanup stuff, I would either
have to use a very small font, a very large monitor or scroll about to
see it all.
What I'm getting at, is that whilst it may appear to be 'clear' the
sheer amount of code means we can't easily see what is happening.
I'd also bet that there is significant duplication within the class(es)
.. If we have to do 3 nested for loops here, you can 'usually' bet
another place in the code base is doing the same nested loops.
Where as, if we separated 'query', 'retrieval' and 'do stuff to',
applied the appropriate design patterns (visitor, command what ever..)
then we usually end up with much smaller methods, no or little
duplication and just as easy and clear code.