Re: Only one point of return
* James Kanze:
On Aug 1, 11:11 am, "Alf P. Steinbach" <al...@start.no> wrote:
* cppques...@googlemail.com:
A colleague told me that there is a rule about good stype that a
function in C++ should have only one point of return (ie. return
statement). Otherwise there might be trouble.
I never heard about it and doubt it.
Anybody heard of it? What would be the advantage?
It's called SESE (Single Entry Single Exit), as opposed to SEME (Single
Entry Multiple Exit).
SESE is a good idea in languages like C, which have no provision for
cleaning up automatically on function return. There, when maintaining
code, you don't want cleanup code to be jumped over by an early return.
The issue has more to do with understanding and reasoning about
code than with the any cleanup code.
Well, that's a generalization: cleanup code is just the most important
in practice, because maintainance is more important than original
development. You may be one of the lucky people who has not had to help
maintain C systems with 600 to 1000 line functions, evolved haphazardly.
I can assure that you such systems are very common, for you see, most
programmers are average. And the average programmer who maintains such
code has a tendency to introduce early returns that skip cleanup code
(often this is later corrected by duplicating the cleanup code in
question, which then gets out of synch, and so on and on).
C++ code, on the other hand, must be prepared to handle exceptions at
any point, i.e. it's multiple exit at the outset.
I've noticed that in well written C++, any exceptions tend to
cluster at the top of the function, in a manner coherent with
the one frequently accepted exception: checking pre-conditions.
You don't want to exit code at just any old point.
You're IMO right that it's best to not hide exits deeply nested in
masses of other code, but C++ code must be /prepared/ to exit any point.
Or at least, if it's written by competent people, it will be
designed for that, using RAII. So there's much less that can
go wrong by using early normal returns, and the only factor
should be what's more /clear/, in the context of a given
function.
Example:
bool f()
{
if( !pointer1) return false;
pointer1->doSomething();
if( !pointer2) return false;
pointer2->doSomething1();
return true;
}
Bad, because it uses global variables, and is unclear.
Are you really want it to do one of the things without doing both?
But if so, try
bool f()
{
if( pointer1 != 0 )
{
pointer1->doSomething();
if( pointer1 != 0 )
{
pointer2->doSomething1();
return true;
}
Just curious, but what invariants hold here?
}
return false;
}
"Invariants" is not really meaningful here. But at the point you
indicate, you can assert(pointer1!=0), so that's an invariant of sorts.
Also, at that point pointer1-doSometing() has been executed.
Which is easily (and more clearly) rewritten as:
bool
f()
{
bool succeeded = false ;
if ( pointer1 != NULL ) {
pointer1->doSomething() ;
if ( pointer2 != NULL ) {
pointer2->doSomething() ;
succeeded = true ;
}
}
return succeeded ;
}
I wouldn't call that clear, rather completely /misleading/: judging from
the original code, this function succeeds even when it does nothing.
But using a result variable has its charms. E.g. you can set a
conditional breakpoint on the single return statement. The cost is, as
evidenced by the code above, less clarity. ;-)
By naming the condition, you've adding important semantic
content for the reader. Even better would be something like:
bool
maybe1()
{
if ( pointer1 != NULL ) {
pointer1->doSomething() ;
}
return pointer1 != NULL ;
}
bool
maybe2()
{
// Alternate way of writing it...
// (only for those who swear by functional
// programming:-)
return pointer2 != NULL
&& (pointer2->doSomething(), true) ;
}
bool
f()
{
return maybe1() && maybe2() ;
}
(But like you, I have a great deal of difficulty imagining a
case where you'd want to do half the job, and then report that
you'd not done any of it.)
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?