scope - D Programming Language

Menu

- Learn
- Documentation
  - Language Reference
  - Library Reference
  - Command-line Reference
  - Feature Overview
  - Articles
- Downloads
- Packages
- Community
  - Blog
  - Orgs using D
  - Twitter
  - Calendar
  - Discord (community-run)
  - Forums
  - IRC
  - Wiki
  - Issues
  - Contributing
  - Contributors
  - Foundation
  - Security Team
  - Donate
  - Sponsors
- Resources
  - Tour
  - Books
  - Tutorials
  - Tools
  - Editors
  - IDEs
  - run.dlang.io
  - Visual D
  - Acknowledgments
  - D Style
  - Glossary
  - Sitemap

Search
Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.

# scope

As we have seen in the previous chapter, expressions that must always be executed are written in the `finally` block, and expressions that must be executed when there are error conditions are written in `catch` blocks.

We can make the following observations about the use of these blocks:

- `catch` and `finally` cannot be used without a `try` block.
- Some of the variables that these blocks need may not be accessible within these blocks:

      void foo(ref int r) {
          try {
              int addend = 42;

              r += addend;
              mayThrow();

          } catch (Exception exc) {
              r -= addend;           // ← derleme HATASI
          }
      }

  That function first modifies the reference parameter and then reverts this modification when an exception is thrown. Unfortunately, `addend` is accessible only in the `try` block, where it is defined. (Note: This is related to name scopes, as well as object lifetimes, which will be explained in a later chapter.)

- Writing all of potentially unrelated expressions in the single `finally` block at the bottom separates those expressions from the actual code that they are related to.

The `scope` statements have similar functionality to the `catch` and `finally` scopes but they are better in many respects. Like `finally`, the three different `scope` statements are about executing expressions when leaving scopes:

- `scope(exit)`: the expression is always executed when exiting the scope, regardless of whether successfully or due to an exception
- `scope(success)`: the expression is executed only if the scope is being exited successfully
- `scope(failure)`: the expression is executed only if the scope is being exited due to an exception

Although these statements are closely related to exceptions, they can be used without a `try-catch` block.

As an example, let's write the function above with a `scope(failure)` statement:

    void foo(ref int r) {
        int addend = 42;

        r += addend;
        scope(failure) r -= addend;

        mayThrow();
    }

The `scope(failure)` statement above ensures that the `r -= addend` expression will be executed if the function's scope is exited due to an exception. A benefit of `scope(failure)` is the fact that the expression that reverts another expression is written close to it.

`scope` statements can be specified as blocks as well:

        scope(exit) {
            // ... expressions ...
        }

Here is another function that tests all three of these statements:

    void test() {
        scope(exit) writeln("when exiting 1");

        scope(success) {
            writeln("if successful 1");
            writeln("if successful 2");
        }

        scope(failure) writeln("if thrown 1");
        scope(exit) writeln("when exiting 2");
        scope(failure) writeln("if thrown 2");

        throwsHalfTheTime();
    }

If no exception is thrown, the output of the function includes only the `scope(exit)` and `scope(success)` expressions:

    when exiting 2
    if successful 1
    if successful 2
    when exiting 1

If an exception is thrown, the output includes the `scope(exit)` and `scope(failure)` expressions:

    if thrown 2
    when exiting 2
    if thrown 1
    when exiting 1
    object.Exception@...: the error message

As seen in the outputs, the blocks of the `scope` statements are executed in reverse order. This is because later code may depend on previous variables. Executing the `scope` statements in reverse order enables undoing side effects of earlier expressions in a consistent order.

Copyright © 1999-2026 by the D Language Foundation | Page generated by Ddoc on Wed Aug 5 11:24:20 2026