On Wednesday, November 26, 2025 11:42:16 AM Mountain Standard Time Brother Bill 
via Digitalmars-d-learn wrote:
> 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?

The point of scope(exit) is to have code which always runs regardless of
whether that block of code exits normally, or it exits because an exception
was thrown. For instance, maybe you created a file or folder inside your
function in order to do something, but it's not supposed to be left around
afterwards. You can use scope(exit) to then delete that file or folder
without caring whether the function is exiting normally or whether an
exception was thrown. Or maybe what you need to do is have your code lock
and unlock a mutex, and you want to make sure that it always unlocks the
mutex regardless of how the code exits. In that case, you can put the code
to unlock the mutex inside of a scope(exit) statement.

In C++, RAII would often be used for these kinds of situations, which means
that you'd create an object whose type has a destructor which does something
that always needs to be run when that scope exits. You can do the same in D,
but if the code is something that you need for a specific function rather
than needing it in several functions, then using a scope(exit) statement is
simpler, because you don't have to create a type just for that one piece of
code (whereas a struct intended to be used with RAII can make more sense in
cases where it's an operation that you need to do in several places).

scope(success) is then used for cases where you only want something to run
when that block of code exits without an exception being thrown. To use the
same example, maybe you have a file or folder which gets created for that
function to do something, and you don't want it to left around normally, but
you do want it to be left around if something goes wrong so that you can
look at the files to debug the problem. In that case, you can put the code
for removing the files inside of scope(success) so that it only runs when an
exception isn't thrown.

scope(failure) is then used in cases where you want something to only happen
when an exception is thrown. For instance, maybe you want to log the fact
that something went wrong. One place that I commonly use scope(failure) is
in more complex unit tests. For instance, if a test uses one or more loops,
having a scope(failure) statement with writeln makes it easy to print out
information about which iteration of the loop is the one which triggered the
test failure. Basically, a scope(failure) makes sense in any situation where
you might catch an exception, do something, and rethrow the exception, but
you don't actually care about the exception itself. You just want to do
something when the exception is thrown. On the other hand, if you do care
about the exception itself, then you need a try-catch block.

And all three types of scope statements are fundamentally different from
try-catch blocks (even though they use try-catch blocks underneath the
hood), because with a try-catch block, you're specifically declaring a block
of code with try which may throw an exception of some kind, and you're then
declaring a catch block to catch that exception so that you can handle it.
Sometimes, you might rethrow such an exception, but usually, the point of a
try-catch block is to catch and handle an exception. On the other hand,
scope statements are _not_ for handling exceptions. They're purely for
running code. scope(exit) is for running code when a block exits regardless
of how it exits. scope(success) is for running code when a block exits
normally. And scope(failure) is for running code when a block exits via an
exception being thrown. In no case are they attempthing to handle the
exception (and in the case of scope(success), there is no exception).

- Jonathan M Davis




Reply via email to