scope(failure) - Programming in D, doesn't catch throw. When should scope (failure) be used?

Brother Bill brotherbill at mail.com
Wed Nov 26 18:42:16 UTC 2025


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 at 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]

```


More information about the Digitalmars-d-learn mailing list