In Linux workstation, the expanded example from Programming in D, bottom of page 206 crashed. Is this expected behavior? I would have expected that the scope(failure) would catch the throw and continue the program. The exception message is intentionally useless.

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

I would expect if that is so, then the program shouldn't crash.

If this is correct, when should scope(exit), scope(success) and scope(error) be used, if ever?
Am I missing any CLI arguments?

source/app.d
```
import std.stdio;

void main()
{
        int a = 100;

        scope_and_may_throw_in_same_block_fail(a);
        // scope_and_may_throw_in_different_blocks_fail(a);
        // scope_and_may_throw_in_same_block_inside_try_catch_success(a);
// no_scope_and_may_throw_in_same_block_inside_try_catch_success(a); // scope_and_may_throw_in_different_blocks_inside_try_catch_fail(a);

        writeln(__LINE__, " main: after scope_function, a = ", a);
}

void mayThrow()
{
// A completely useless exception message. I have seen too many of these in the wild.
        throw new Exception("You shouldn't have done that!");
}

// Writes out line 31 and 33 with stack trace, doesn't write line 13
void scope_and_may_throw_in_same_block_fail(ref int r)
{
        writeln("--- scope_and_may_throw_in_same_block_fail ---");
        int addend = 42;

        r += addend;

        scope (failure)
        {
writeln(__LINE__, " scope_and_may_throw_in_same_block_fail: scope before subtraction, r = ", r);
                r -= addend;
writeln(__LINE__, " scope_and_may_throw_in_same_block_fail: scope after subtraction, r = ", r);
        }

        mayThrow();
}

// Writes out stack trace only, doesn't write lines 50, 52, 13
void scope_and_may_throw_in_different_blocks_fail(ref int r)
{
        writeln("--- scope_and_may_throw_in_different_blocks_fail ---");
        int addend = 42;

        r += addend;

        {
                scope (failure)
                {
writeln(__LINE__, " scope_and_may_throw_in_different_blocks_fail: scope before subtraction, r = ", r);
                        r -= addend;
writeln(__LINE__, " scope_and_may_throw_in_different_blocks_fail: scope after subtraction, r = ", r);
                }
        }

        mayThrow();
}

// Writes out lines 72, 74, 81, and 12, without stack trace. On line 13, a = 100 void scope_and_may_throw_in_same_block_inside_try_catch_success(ref int r)
{
writeln("--- scope_and_may_throw_in_same_block_inside_try_catch_success ---");
        int addend = 42;

        r += addend;

        try
        {
// This scope block only runs after an exception is thrown in the same scope, within braces on lines 18 and 28
                scope (failure)
                {
writeln(__LINE__, " scope_and_may_throw_in_same_block_inside_try_catch_success: scope before subtraction, r = ", r);
                        r -= addend;
writeln(__LINE__, " scope_and_may_throw_in_same_block_inside_try_catch_success: scope after subtraction, r = ", r);
                }

                mayThrow();
        }
        catch (Exception exc)
        {
                writeln(__LINE__, " Caught scope (failure)");
        }
}

// Writes out lines 100, 102, 104, and 13, without stack trace. On line 13, a = 100 void no_scope_and_may_throw_in_same_block_inside_try_catch_success(ref int r)
{
writeln("--- noscope_and_may_throw_in_same_block_inside_try_catch_success ---");
        int addend = 42;

        r += addend;

        try
        {
                mayThrow();
        }
        catch (Exception exc)
        {
                writeln(__LINE__, " Caught no_scope (failure)");

writeln(__LINE__, " no_scope_and_may_throw_in_same_block_inside_try_catch_success: scope before subtraction, r = ", r);
                r -= addend;
writeln(__LINE__, " no_scope_and_may_throw_in_same_block_inside_try_catch_success: scope after subtraction, r = ", r);
        }
}

// Writes out lines 108 and 13, without stack trace. On line 12, a = 142, when a should be 100. void scope_and_may_throw_in_different_blocks_inside_try_catch_fail(ref int r)
{
writeln("--- scope_and_may_throw_in_different_blocks_inside_try_catch_fail ---");
        int addend = 42;

        r += addend;

        try
        {
// This scope block only runs after an exception is thrown in the same scope, within braces on lines 96 - 103
                {
                        scope (failure)
                        {
writeln(__LINE__, " scope_and_may_throw_in_different_blocks_inside_try_catch_fail: scope before subtraction, r = ", r);
                                r -= addend;
writeln(__LINE__, " scope_and_may_throw_in_different_blocks_inside_try_catch_fail: scope after subtraction, r = ", r);
                        }
                }

                mayThrow();
        }
        catch (Exception exc)
        {
                writeln(__LINE__, " Caught scope (failure)");
        }
}

```

Console output
```
--- scope_and_may_throw_in_same_block_fail ---
32 scope_and_may_throw_in_same_block_fail: scope before subtraction, r = 142 34 scope_and_may_throw_in_same_block_fail: scope after subtraction, r = 100
object.Exception@source/app.d(19): You shouldn't have done that!
----------------
source/app.d:19 void app.mayThrow() [0x400c98]
source/app.d:37 void app.scope_and_may_throw_in_same_block_fail(ref int) [0x400cce]
source/app.d:7 _Dmain [0x400c2f]

```

Reply via email to