Reasons for single entry, single exit
Thanks for the clarification; I misunderstood. It seems that McCabe
graphs don't really support either SEME or SESE, since you can produce
good SEME and SESE code as well as bad (as measured by McCabe graphs).
Here's my take on this debate:
Whenever implementing a function, I have to satisfy (broadly speaking)
two goals:
-- implement the desired behavior
-- follow naming conventions, style guides, coding conventions, etc.
It's my opinion that we want to skew our mental effort to the first
goal as much as possible.
(Note: In this post I'm speaking only about implementation, as opposed
to other activities such as ****ysis or design, where we do need to
spend more effort on things besides simple correctness.)
Obviously, if these two goals ever conflict, satisfying the first goal
has to take precedence.
This suggests a criterion for evaluating subgoals for inclusion in the
second goal: any subgoal that conflicts with the first goal (i.e.,
interferes with function correctness) should be left out. (This is why
I look at rules like "never use exceptions" or "never dynamically
allocate memory" with skepticism; such rules can easily interfere with
correctness.)
Note that, for the most part, naming conventions, indenting styles and
so forth don't conflict with correctness. The only way these things
interact with correctness is if the conventions in use are foreign
enough to a programmer as to be error-prone.
This suggests a second criterion: any subgoal under consideration for
inclusion in the second goal should require relatively little mental
effort, because the more effort required, the more likely the subgoal
will lead to errors. For example, a formatting convention that has
programmers place each token on a separate line with no indenting
would involve a great deal of effort to both read and write correctly,
so it isn't a very good convention. On the other hand, a rule like
"open curly braces always go on the next line," while it may seem
distateful to some, can be used with almost no mental overhead, and is
therefore worth considering.
So where do SESE and SEME come in? Obviously, they don't interact
directly with correctness (many functions can be either SESE or SEME
and still be correct), so they belong (if anywhere) in the second
goal. Second, SESE vs. SEME is not an exclusive choice, because
sometimes, while following SEME guidelines, I will write a SESE
function, simply because, for that function, SESE is the only sensible
option. The choice is therefore between SESE-only vs. a SESE/SEME
combination.
For myself, I reject the SESE-only choice because it leads to
situations where I have to spend too much effort on the second goal --
eventually I will have to implement a function for which I will have
to spend significant mental effort on something other than
correctness: simply getting the function to be SESE.
I don't have an example handy, but at various times during my career
I've had to program in an SESE style, and eventually, I come to a
function for which getting the function to be SESE involves effort on
par with the effort of just getting the function correct. As a result,
I've had to fix bugs that existed simply because a function was
written to have a single exit, where a multiple-exit function would
have been simpler to implement and therefore less likely to have bugs
in the first place. I don't know how to characterize such functions,
other than to say that they are more complex when implemented as SESE.
If you've managed to read this far, you have no doubt noticed that
what I've written is very subjective. It's all my opinion, but I
believe that the ideas I've laid out can provide a useful framework
for discussing the issues (not just SESE vs. SEME, but other "second
goal" type issues).
Further, objective complexity measures are all well and good, but
subjective complexity is extremely important as well; after all, the
code will have to be written and maintained by people with subjective
impressions of what's complex and what's not.
Therefore, I think it's perfectly valid to have coding rules like "use
multiple exit wherever it makes sense." Such a rule is no more
subjective than "never use multiple exit."
Bob Bell
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|