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

Reply via email to