Drawbacks of exceptions being globally allocated
Tejas
notrealemail at gmail.com
Sun Aug 15 18:47:27 UTC 2021
On Sunday, 15 August 2021 at 16:23:25 UTC, Ali Çehreli wrote:
> On 8/15/21 2:10 AM, Alexandru Ermicioi wrote:
>
> >> 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.
>
> > That is just an assumption.
>
> Agreed but it's based on hands-on experience as well as
> exposure to these forums. :)
>
> > There could be designs where original
> > exception gets wrapped in another one
>
> Wrapping is different and yes, it is useful. There have been
> cases where I hit a ConvException which only tells me a
> conversion failed. I do catch and augment it in outer contexts
> to saying something similar ot "That happened while doing this".
>
> > Regarding exception chaining, do you mean that it will
> automatically get
> > chained, even without explicitly passing it as constructor of
> wrapping
> > exception?
>
> Yes. That's the functionality which isn't very useful because
> the collateral exceptions are usually because of the main one:
> Imagine the file system is full and a destructor cannot flush a
> file. The destructor's error is not interesting in this case.
>
> class Main : Exception {
> this() {
> super("Main failed");
> }
> }
>
> class Dtor : Exception {
> this() {
> super("The destructor failed");
> }
> }
>
> struct S {
> ~this() {
> throw new Dtor();
> }
> }
>
> import std.stdio;
>
> void main() {
> try {
> auto s = S();
> throw new Main();
>
> } catch (Exception exc) {
> stderr.writeln("Failed: ", exc.msg);
> stderr.writeln("This failed too: ", exc.next.msg);
> // (Of course, real code should stop when 'next' is null.)
> }
> }
>
> That output contains two automatically chained exceptions:
>
> Failed: Main failed
> This failed too: The destructor failed
>
> Ali
Do you see anything wrong with the following `emplace`-allocated,
RAII following exceptions:
```d
import std;
import core.stdc.stdlib;
class Main : Exception {
this() @nogc{
super("Main Failed");
}
}
class Dtor : Exception {
this() @nogc{
super("The destructor failed");
}
}
T heapAllocate(T, Args...)(Args args)@nogc{
auto size = __traits(classInstanceSize, T);
auto memory = malloc(size)[0 .. size];
auto instance = emplace!(T,Args)(memory, args);
return instance;
}
struct S {
~this()@nogc {
scope a = heapAllocate!Dtor();
throw a;
}
}
void main() @nogc{
try {
auto s = S();
scope a = heapAllocate!Main();
throw a;
} catch (Exception exc) {
printf("Failed: %s\n", cast(char*)exc.msg);
printf("This failed too: %s\n", cast(char*)exc.next.msg);
// (Of course, real code should stop when 'next' is null.)
}
}
```
Is this good enough for general use now? Any other drawbacks?
More information about the Digitalmars-d-learn
mailing list