Re: break, continue, goto
Re: break, continue, goto
- Subject: Re: break, continue, goto
- From: Thomas Harrington <email@hidden>
- Date: Thu, 7 Aug 2003 17:04:32 -0600
On Wednesday, August 6, 2003, at 03:04 AM, Yuhui wrote:
While I can understand the use for a goto, I've learned in my
experience that most goto's can be replaced with methods. I think
there's more flexibility with methods because you can more easily
"expand" them to accomodate bug fixes or add new features/functions.
Also, if there are several goto statements in different parts of the
program that use a particular block of code, then methods would reduce
redundancy.
E.g. in (b), instead of "goto errexit", I could say "errexit()". The
same would apply for (c).
Your suggestions seem unnecessarily dogmatic, and will not in general
simplify the code. Look at the example again, only this time imagine
that the function is much longer and that there are a dozen or so
buffers that may need cleaning up. What then about your errexit()
function? You'd need to pass in references to all of those buffers in
order to free() them. Then imagine that there's more to clean up than
just freeing of buffers-- for example, sockets to shut down and files
to close. You end up with an errexit() function with a long list of
arguments of various types. Every time you edit the code you need to
edit not just errexit()'s code but also its signature, adding another
point of failure in the code. And in practice you're unlikely to be
able to reduce redundancy by reusing errexit(). You'll find that
you've increased complexity rather than reducing it, and the only
purpose served by the change is dogmatic avoidance of 'goto'.
I agree that 'goto' should only be used after careful consideration of
the situation, but really, that rule applies to almost any programming
statement.
(b) When you need to provide a standard set of error handling/clean-up
code for the duration of a function body. In this situation, you are
using goto like a C++ throw; e.g.
void *myFunction(void) {
void *buffer = malloc (65536);
if (!buffer)
return NULL;
if (doSomethingWithBuffer() < 0)
goto errexit;
if (doSomethingElseWithBuffer() < 0)
goto errexit;
return buffer;
errexit:
free (buffer);
return NULL;
}
This is a *lot* clearer than writing the error handling/clean-up code
over and over again, and there really isn't any better way to do this
with plain C.
--
Tom Harrington
email@hidden
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.