|
![](/i/fill.gif) |
Warp wrote:
There's really one primary problem with early returns, and that's handling
things that ought be handled before the function returns, like deallocating
memory, closing files, logging, etc. In a decent language like C++, there's
invisible bits of code stuck into your object code before each return (or,
alternately, the compiler rewrites the return statement to be a goto to the
end of the function). Without that, it requires somewhat more code to return
early *and* clean up, to the point where skipping over blocks with flags
might be more clear and maintainable than duplicating clean-up code.
Especially if you want to DRY on the cleanup code.
Someone way back proved you could turn *any* control flow into structured
flow, with enough booleans and repeated code. That doesn't mean it's a good
idea.
And of course, this is all local to a fairly small function. Think about a
program with significant amounts of control flow using setjmp/longjmp, or
where gotos can go to any label anywhere in a program, and you get the idea
of what Dr D was arguing against.
It turns out that what's really formally the problem is more the labels than
the gotos. The problem is if you look at the preconditions of the label,
it's an amalgamation of all the postconditions of every goto that goes to
that label. You can't look at the line before the label and the line after
the label and know *anything* about any of the variables or program state
when you reach the line after the label, unless you hunt down and analyze
every goto as well.
> Likewise no "fall-through" in switch-case blocks in languages like C
I like how C# handles this. Each branch has to end with either a break or a
goto X, where X is one of the labels of the switch. So you can rearrange the
order of the branches, insert branches in the middle, etc, and not break
anything. And you can't accidentally fall through to the next case and bring
down the entire east coast telecommunication infrastructure. ;-)
> The more such error situations there could be, the more indentation the
> code would require which is not only inconvenient but also IMO makes the
> code less readable.
I find another way of doing this also works. My own invention:
bool worked = true;
if (worked) worked = try_thing_one();
if (worked) { reset_flobulator(); worked = query_flobulator(); }
if (worked) worked = yidda < 27;
clean_up_temps();
return worked;
and so on. Each block of work can be rearranged, nothing runs and it falls
out very quickly on failure, everything inline, everything's indented only
one, yet it's pretty easy to follow what's going on. And of course if you
want specific error codes, that works just as easily.
--
Darren New, San Diego CA, USA (PST)
Serving Suggestion:
"Don't serve this any more. It's awful."
Post a reply to this message
|
![](/i/fill.gif) |