digitalmars.D - nogc and Exceptions
- Quirin Schroll (65/65) Sep 29 2022 In the [Q&A of Átila’s talk at DConf at
- Adam D Ruppe (14/17) Sep 29 2022 It actually already does this. Even if you malloc an exception
- IGotD- (4/16) Sep 29 2022 Deallocation is just as interesting for completeness in this
- Guillaume Piolat (10/18) Sep 29 2022 Why not allow to throw an immutable(char)[] value instead of
- Adam D Ruppe (12/16) Sep 29 2022 At that point, you might as well just throw an immutable static
- rikki cattermole (3/3) Sep 29 2022 Something that I've been working on, although I'm not 100% there yet I
- Quirin Schroll (4/7) Sep 30 2022 I’ve skimmed your draft and it looks interesting. I’ll read it
In the [Q&A of Átila’s talk at DConf at 1:13:45](https://youtu.be/ksNGwLTe0Ps?t=4425), someone asks if allocating and throwing exceptions might be a the case where you wouldn’t mind the GC even in supposed ` nogc` code: When an `Error` is thrown, the application is doomed anyways; when an `Exception` is thrown, you already subscribed to inefficient execution. There’s a few options: * Ignore the issue at a language level and just lie (code below): Make an `Exception` allocating function and cast it to ` nogc`. I do not know if that is UB. * Make ` nogc` not apply to a `Throwable` allocated in a `throw` expression. * Introduce Yet Another Damn Function Attribute (YADMA) ` nogcUnlessThrown`. The code to lie: ```d template throw_new(E : Throwable, Args...) { alias doAllocate = function E(Args args) => new E(args); noreturn throw_new(Args args) nogc { import std.algorithm.comparison : among; enum isSafe = " safe".among(__traits(getFunctionAttributes, doAllocate)) > 0; enum isPure = "pure".among(__traits(getFunctionAttributes, doAllocate)) > 0; alias FP = mixin("E function(Args) nogc ", isSafe ? " safe " : "", isPure ? "pure" : ""); immutable hackedAllocate = (() trusted => cast(FP)(doAllocate))(); throw hackedAllocate(args); } } void test() nogc safe pure { import std.format : FormatException; throw_new!FormatException("msg"); } void main() safe { import std.format : FormatException; try { test(); } catch (FormatException e) { import std.stdio; writeln(e.msg); } } ``` Some explanation for why it is like this: * One has to use `alias doAllocate = function E(Args args) => new E(args);` instead of a normal function definition because a normal function definition does not infer attributes. `throw_new` has attributes inferred. * `isSafe` and `isPure` take care that those attributes are carried through if `E`’s constructor happens to have them. * `hackedAllocate` is created via a ` trusted` block because adding ` nogc` is not ` safe`. It only trusts the cast, not the call. * Perfect forwarding for the arguments is not trivial (I tried), but probably not needed anyway.
Sep 29 2022
On Thursday, 29 September 2022 at 12:12:34 UTC, Quirin Schroll wrote:* Ignore the issue at a language level and just lie (code below): Make an `Exception` allocating function and cast it to ` nogc`. I do not know if that is UB.It actually already does this. Even if you malloc an exception (which you can), the exception's ctor will call the trace info hook, which GC allocates yet lies about it. i've written a few random things about exceptions over the last year: http://dpldocs.info/this-week-in-d/Blog.Posted_2021_08_16.html http://dpldocs.info/this-week-in-d/Blog.Posted_2021_08_23.html http://dpldocs.info/this-week-in-d/Blog.Posted_2022_06_27.html http://dpldocs.info/this-week-in-d/Blog.Posted_2022_08_01.html#exception-template-concept including some talk about just lying. nogc is kinda silly to begin with and if you want both nogc and nothrow you can... write nogc nothrow.
Sep 29 2022
On Thursday, 29 September 2022 at 12:12:34 UTC, Quirin Schroll wrote:Some explanation for why it is like this: * One has to use `alias doAllocate = function E(Args args) => new E(args);` instead of a normal function definition because a normal function definition does not infer attributes. `throw_new` has attributes inferred. * `isSafe` and `isPure` take care that those attributes are carried through if `E`’s constructor happens to have them. * `hackedAllocate` is created via a ` trusted` block because adding ` nogc` is not ` safe`. It only trusts the cast, not the call. * Perfect forwarding for the arguments is not trivial (I tried), but probably not needed anyway.Deallocation is just as interesting for completeness in this example which was left out for some reason.
Sep 29 2022
On Thursday, 29 September 2022 at 12:12:34 UTC, Quirin Schroll wrote:There’s a few options: * Ignore the issue at a language level and just lie (code below): Make an `Exception` allocating function and cast it to ` nogc`. I do not know if that is UB. * Make ` nogc` not apply to a `Throwable` allocated in a `throw` expression. * Introduce Yet Another Damn Function Attribute (YADMA) ` nogcUnlessThrown`.Why not allow to throw an immutable(char)[] value instead of Exception? No destruction, allocation, and nogc, and no DIP 1008 needed. And it's usually enough for errors. It would break chaining I guess. Breaking the type system ( nogc) breaks D programs without runtime, or an impaired runtime. For sure one can rewrite it all with error codes, but well.
Sep 29 2022
On Thursday, 29 September 2022 at 23:35:51 UTC, Guillaume Piolat wrote:Why not allow to throw an immutable(char)[] value instead of Exception?At that point, you might as well just throw an immutable static Error instance.Breaking the type system ( nogc) breaks D programs without runtime, or an impaired runtime.nogc and no druntime are entirely separate concepts. There's a little bit of overlap, but it is really easy to throw an exception allocated differently right now or otherwise depend on druntime while still satisfying nogc that it is maybe a useful filter reminder, but not at all comprehensive. The most reliable way to see if something is no druntime compatible is to build it with no druntime and look for linker errors.
Sep 29 2022
Something that I've been working on, although I'm not 100% there yet I think. https://github.com/rikkimax/DIPs/blob/value_type_exceptions/DIPs/DIP1xxx-RC.md
Sep 29 2022
On Friday, 30 September 2022 at 00:00:04 UTC, rikki cattermole wrote:Something that I've been working on, although I'm not 100% there yet I think. https://github.com/rikkimax/DIPs/blob/value_type_exceptions/DIPs/DIP1xxx-RC.mdI’ve skimmed your draft and it looks interesting. I’ll read it properly later today.
Sep 30 2022