Drawbacks of exceptions being globally allocated

Ali Çehreli acehreli at yahoo.com
Sun Aug 15 00:15:32 UTC 2021


On 8/14/21 4:41 AM, Tejas wrote:

 > What is the drawback of the following "simple" ```@nogc``` exception
 > creation technique?
 >
 > ```d
 > import std;
 > void main()@nogc
 > {
 >      try{
 >          __gshared a = new Exception("help");
 >          scope b = a;
 >          throw b;
 >      }
 >      catch(Exception e){
 >          printf("caught");
 >      }
 > }
 > ```

So, there would be many exception objects one for each place that an 
exception can be thrown. Functions like enforce() would have to take a 
reference to the exception object that is associated with that local scope.

I don't have a clear idea on whether it would work or whether it would 
be cumbersome to use or not. I wrote the following by misunderstanding 
you. I thought you you were proposing just one exception object for the 
whole program. I am still posting it because it is something I realized 
relatively recently.

Even though this feature is probably never used, in D, multiple 
exception objects are chained. For example, you can throw e.g. in a 
destructor when there is an active exception in flight and that second 
object gets attached to the first one in linked list fashion.

This may be useful in some cases but in general, these colatteral 
exceptions don't carry much information and I don't think anybody looks 
at them. Usually, the first one is the one that explains the error case.

All such collateral exceptions are accessible through the Throwable.next 
function.

However, even if D did not have such a feature and it had only a single 
exception that could be thrown (like in C++), the reality is, there can 
be infinite number of exceptions objects alive. This fact is true for 
C++ as well and this fact is one of the main reasons why exceptions are 
not allowed in safety-critical systems: When you can't limit the number 
of exception objects, you can't guarantee that the system will not run 
out of memory.

Here is how even in C++ there can be infine exception objects. (Note: 
Yes, there is only one in flight but there is no limit on the number of 
caught exception objects that are alive.)

try {
   foo();

} catch (Exception exc) {
   // Note: We caught the exception; so it's not in flight anymore

   bar();

   // For the following to work, exc must be alive even after bar()
   writeln(exc.msg);
}

Now imagine bar() had a try-catch of its own where it caught another 
exception. During the execution of bar's catch clause, there are two 
exception objects alive.

So, the problem with your proposal is, there is no room for the 
exception that was throw during bar's execution.

Ali



More information about the Digitalmars-d-learn mailing list