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
