Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Structured programming
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
===Early exit=== {{further|Return early}} The most common deviation from structured programming is '''early exit''' from a function or loop. At the level of functions, this is a <code>return</code> statement. At the level of loops, this is a <code>break</code> statement (terminate the loop) or <code>continue</code> statement (terminate the current iteration, proceed with next iteration). In structured programming, these can be replicated by adding additional branches or tests, but for returns from nested code this can add significant complexity. [[C (programming language)|C]] is an early and prominent example of these constructs. Some newer languages also have "labeled breaks", which allow breaking out of more than just the innermost loop. Exceptions also allow early exit, but have further consequences, and thus are treated below. Multiple exits can arise for a variety of reasons, most often either that the subroutine has no more work to do (if returning a value, it has completed the calculation), or has encountered "exceptional" circumstances that prevent it from continuing, hence needing exception handling. The most common problem in early exit is that cleanup or final statements are not executed – for example, allocated memory is not deallocated, or open files are not closed, causing [[memory leak]]s or [[resource leak]]s. These must be done at each return site, which is brittle and can easily result in bugs. For instance, in later development, a return statement could be overlooked by a developer, and an action that should be performed at the end of a subroutine (e.g., a [[Tracing (software)|trace]] statement) might not be performed in all cases. Languages without a return statement, such as standard [[Pascal (programming language)|Pascal]] and [[Seed7]], do not have this problem. Most modern languages provide language-level support to prevent such leaks;<ref>{{cite tech report |first1=Matt |last1=Elder |first2=Steve |last2=Jackson |first3=Ben |last3=Liblit |title=Code Sandwiches |institution=[[University of Wisconsin–Madison]] |date=October 2008 |id=1647 |url=http://research.cs.wisc.edu/techreports/2008/TR1647.pdf}}</ref> see detailed discussion at [[resource management (computing)|resource management]]. Most commonly this is done via unwind protection, which ensures that certain code is guaranteed to be run when execution exits a block; this is a structured alternative to having a cleanup block and a <code>goto</code>. This is most often known as <code>try...finally,</code> and considered a part of [[exception handling]]. In case of multiple <code>return</code> statements introducing <code>try...finally,</code> without exceptions might look strange. Various techniques exist to encapsulate resource management. An alternative approach, found primarily in C++, is [[Resource Acquisition Is Initialization]], which uses normal stack unwinding (variable deallocation) at function exit to call destructors on local variables to deallocate resources. [[Kent Beck]], [[Martin Fowler (software engineer)|Martin Fowler]] and co-authors have argued in their [[refactoring]] books that nested conditionals may be harder to understand than a certain type of flatter structure using multiple exits predicated by [[guard clause]]s. Their 2009 book flatly states that "one exit point is really not a useful rule. Clarity is the key principle: If the method is clearer with one exit point, use one exit point; otherwise don’t". They offer a cookbook solution for transforming a function consisting only of nested conditionals into a sequence of guarded return (or throw) statements, followed by a single unguarded block, which is intended to contain the code for the common case, while the guarded statements are supposed to deal with the less common ones (or with errors).<ref>{{cite book |author1=Jay Fields|author2=Shane Harvie|author3=Martin Fowler|author4=Kent Beck |title=Refactoring: Ruby Edition|year=2009|publisher=Pearson Education|isbn=978-0-321-60350-0|pages=274–279}}</ref> [[Herb Sutter]] and [[Andrei Alexandrescu]] also argue in their 2004 C++ tips book that the single-exit point is an obsolete requirement.<ref>{{cite book|author1=Herb Sutter|author2=Andrei Alexandrescu|title=C++ Coding Standards: 101 Rules, Guidelines, and Best Practices|year=2004|publisher=Pearson Education |isbn=978-0-13-265442-5 |quote=Example 4: Single entry, single exit ("SESE"). Historically, some coding standards have required that each function have exactly one exit, meaning one return statement. Such a requirement is obsolete in languages that support exceptions and destructors, where functions typically have numerous implicit exits.}}</ref> In his 2004 textbook, [[David Watt (computer scientist)|David Watt]] writes that "single-entry multi-exit control flows are often desirable". Using Tennent's framework notion of [[S-algol|sequencer]], Watt uniformly describes the control flow constructs found in contemporary programming languages and attempts to explain why certain types of sequencers are preferable to others in the context of multi-exit control flows. Watt writes that unrestricted gotos (jump sequencers) are bad because the destination of the jump is not self-explanatory to the reader of a program until the reader finds and examines the actual label or address that is the target of the jump. In contrast, Watt argues that the conceptual intent of a return sequencer is clear from its own context, without having to examine its destination. Watt writes that a class of sequencers known as ''escape sequencers'', defined as a "sequencer that terminates execution of a textually enclosing command or procedure", encompasses both breaks from loops (including multi-level breaks) and return statements. Watt also notes that while jump sequencers (gotos) have been somewhat restricted in languages like C, where the target must be an inside the local block or an encompassing outer block, that restriction alone is not sufficient to make the intent of gotos in C self-describing and so they can still produce "[[spaghetti code]]". Watt also examines how exception sequencers differ from escape and jump sequencers; this is explained in the next section of this article.{{sfn|Watt|Findlay|2004|pp=215–221}} In contrast to the above, [[Bertrand Meyer]] wrote in his 2009 textbook that instructions like <code>break</code> and <code>continue</code> "are just the old <code>goto</code> in sheep's clothing" and strongly advised against their use.<ref name="Meyer2009">{{cite book|author=Bertrand Meyer|title=Touch of Class: Learning to Program Well with Objects and Contracts|year=2009|publisher=Springer Science & Business Media|isbn=978-3-540-92144-8|page=189}}</ref>
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)