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