On Friday, 19 May 2017 at 15:45:28 UTC, Mike Parker wrote:
DIP 1008 is titled "Exceptions and @nogc".
https://github.com/dlang/DIPs/blob/master/DIPs/DIP1008.md
All review-related feedback on and discussion of the DIP should
occur in this thread. The review period will end at 11:59 PM ET
on June 2 (3:59 AM GMT June 3), or when I make a post declaring
it complete.
At the end of Round 1, if further review is deemed necessary,
the DIP will be scheduled for another round. Otherwise, it will
be queued for the formal review and evaluation by the language
authors.
Extensive discussion of this DIP has already taken place in two
threads, both linked from the document. You may find it
beneficial to skim through those threads before posting any
feedback here.
Thanks in advance to all who participate.
Destroy!
As many others, I dislike special-casing "throw new" and enough
has been said about that.
I also don't like adding hooks to druntime, or that by doing so
the allocation strategy is baked in (but I guess only when using
the `new` operator so there's that).
I think maybe the problem isn't with `throw` but with `catch`.
What if instead we make it so that:
catch(scope T ex) { /*...*/; }
Means:
catch(scope T ex) { /*...*/; ex.__dtor; }
That way whoever is throwing the exception allocates however he
or she sees fit and the memory is handled by the class's
destructor. Sort of proof of concept using malloc (if I did this
for real I'd use std.allocator):
class MallocException: Exception {
char* buffer;
size_t length;
// has to be public or `emplace` won't compile
this(string msg) @nogc {
import core.stdc.stdlib: malloc;
length = msg.length;
buffer = cast(char*)malloc(length);
buffer[0 .. length] = msg[];
super(cast(string)buffer[0 .. length]);
}
~this() @nogc {
import core.stdc.stdlib: free;
free(buffer);
free(cast(void*)this);
}
static MallocException create(string msg) @nogc {
import core.stdc.stdlib: malloc;
import std.conv: emplace;
enum size = __traits(classInstanceSize, MallocException);
auto buf = malloc(size);
return emplace!MallocException(buf[0 .. size], msg);
}
}
void main() @nogc {
try {
import core.stdc.stdlib: malloc;
throw MallocException.create("oops");
} catch(MallocException ex) {
ex.__dtor;
}
}
The code above works today, the annoying thing is having to
invoke the destructor manually (and also knowing it's called
`__dtor`).
This would however mean delaying making phobos @nogc since each
`throw` site would have to be changed.
And if someone never remembers to catch by scope somewhere and is
allocating memory themselves, well... use the GC, Luke.
Atila