www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - throw Exception with custom message in nogc code

reply poliklosio <poliklosio happypizza.com> writes:
I need to throw some exceptions in my code, but I don't want to 
ever care about the garbage collector.

I have seen some solutions to throwing exceptions in nogc code, 
but only toy examples, like
https://p0nce.github.io/d-idioms/#Throwing-despite- nogc

The solution sort of works, but doesn't show how to pass a custom 
string to the exception, and the text says "This trick is a dirty 
Proof Of Concept. Just never do it.".
Is there a solution?
Jun 04 2016
next sibling parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 06/04/2016 05:05 PM, poliklosio wrote:
 I need to throw some exceptions in my code, but I don't want to ever
 care about the garbage collector.

 I have seen some solutions to throwing exceptions in nogc code, but only
 toy examples, like
 https://p0nce.github.io/d-idioms/#Throwing-despite- nogc

 The solution sort of works, but doesn't show how to pass a custom string
 to the exception, and the text says "This trick is a dirty Proof Of
 Concept. Just never do it.".
 Is there a solution?
Regardless of the sanity or the usefulness of the idiom, it's possible to mutate the .msg property of the exception object: import std.stdio; class MyException : Exception { this(string msg) { super(msg); } void setMessage(string msg) nogc { super.msg = msg; } } // Statically initialize an exception instance. MyException g_Exception; static this() { g_Exception = new MyException("This message won't be helpful"); } // Function that throws despite being nogc void nogcFunction() nogc { g_Exception.setMessage("Helpful message"); throw g_Exception; } void main() { try { nogcFunction(); } catch(const(Exception) e) { // Message, file and line number won't be given though import std.stdio; writefln("Received an exception: %s", e.msg); } } Outputs Received an exception: Helpful message Ali
Jun 04 2016
prev sibling parent reply HubCool <HubCool bichecake.kl> writes:
On Sunday, 5 June 2016 at 00:05:15 UTC, poliklosio wrote:
 I need to throw some exceptions in my code, but I don't want to 
 ever care about the garbage collector.

 I have seen some solutions to throwing exceptions in nogc code, 
 but only toy examples, like
 https://p0nce.github.io/d-idioms/#Throwing-despite- nogc

 The solution sort of works, but doesn't show how to pass a 
 custom string to the exception, and the text says "This trick 
 is a dirty Proof Of Concept. Just never do it.".
 Is there a solution?
You can also "make!TheExceptionType(Mallocator.instance, message)" And you stores them in a fixed length stack. On program termination you free them. But I'd say that the leak doesn't matter. Either the soft has a very small problem that happens once eventually, otherwise it's a big bug and new exceptions will come so often that the program has to be killed immediatly. +--------------------------------------------------+ auto leakAnoGcException(T, A...)(A a) nogc if (is(T: Exception)) { import std.experimental.allocator.mallocator; import std.experimental.allocator; return make!T(Mallocator.instance, a); // eventually stores them ona stack that you can free in static ~this() } void main() nogc { bool ouch; class MyException: Exception {this(string m) nogc {super(m);}} try throw leakAnoGcException!MyException("ouch"); catch (Exception e) {ouch = true;/*can dispose here too...*/} assert(ouch); } +--------------------------------------------------+
Jun 04 2016
parent reply poliklosio <poliklosio happypizza.com> writes:
On Sunday, 5 June 2016 at 06:25:28 UTC, HubCool wrote:
 (...)
 But I'd say that the leak doesn't matter. Either the soft has a 
 very small problem that happens once eventually, otherwise it's 
 a big bug and new exceptions will come so often that the 
 program has to be killed immediatly.

 +--------------------------------------------------+
 auto leakAnoGcException(T, A...)(A a)  nogc
 if (is(T: Exception))
 {
     import std.experimental.allocator.mallocator;
     import std.experimental.allocator;
     return make!T(Mallocator.instance, a);
     // eventually stores them ona stack that you can free in 
 static ~this()
 }

 void main()  nogc
 {
     bool ouch;
     class MyException: Exception {this(string m)  nogc 
 {super(m);}}
     try throw leakAnoGcException!MyException("ouch");
     catch (Exception e) {ouch = true;/*can dispose here 
 too...*/}
     assert(ouch);
 }
 +--------------------------------------------------+
I like your solution, as it doesn't force to allocate exception objects statically, which is a step forward. On the other hand I don't think that the leak doesn't matter. This would only be the case if one could guarantee that only a small, constant number of exceptions is thrown during program execution. This is not generally the case. Also, exceptions are not necessarily for bugs. There may be used sometimes for bug handling when other things like static typing and assertions are not enough, but bug handling is not the core reason for havi ng exceptions in languages. Exceptions is a control flow construct for use in events which occur rarely (relative to normal execution of surrounding code) and require jumping many levels up the call stack. That's all there is to them. Its not some philosophical concept that depends on the definition of errors or bugs. Can you elaborate on how to dispose the exception? I'm partilularly interested in the code you would write in place of the /*can dispose here too...*/ comment.
Jun 05 2016
next sibling parent poliklosio <poliklosio happypizza.com> writes:
On Sunday, 5 June 2016 at 10:37:49 UTC, poliklosio wrote:
 Also, exceptions are not necessarily for bugs. There may be 
 used sometimes for bug handling when other things like static 
 typing and assertions are not enough, but bug handling is not 
 the core reason for havi ng exceptions in languages.
Actually, in D, things like assertions already behave like exceptions jumping up the call stack and generating stack traces so there should be no reason to ever use normal exceptions to handle programmer mistakes. I like this language a little bit more every day I use it.
Jun 05 2016
prev sibling parent HubCool <HubCool bichecake.kl> writes:
On Sunday, 5 June 2016 at 10:37:49 UTC, poliklosio wrote:
 On Sunday, 5 June 2016 at 06:25:28 UTC, HubCool wrote:
 Can you elaborate on how to dispose the exception?
 I'm partilularly interested in the code you would write in 
 place of the /*can dispose here too...*/ comment.
I don't know from where this idea came, I've never seen this, is it allowed ? If so, dispose is not nogc but since exceptions are quite simple classes they can be cleaned by hand without calling the ctor (since there's no ctor...). just Malloc.instance.dispose() would be enough. Even the size is not required (though it can also be retrieved with typeid().initializer.length.
Jun 05 2016