www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - newbie problem with nothrow

reply WhatMeWorry <kheaser gmail.com> writes:
Is there a way to turn off nothrow or work around it? Because to 
me it looks like nothrow prevents me from doing anything useful.

extern(C) void onKeyEvent(GLFWwindow* window, int key, int 
scancode, int action, int modifier) nothrow
{
     if(queue.roomInQueue())
     {
         auto event = new Event;
         event.type = EventType.keyboard;
         event.keyboard.key = cast(Key) key;

         // etc.
}

Error: function 'event_handler.CircularQueue.roomInQueue' is not 
nothrow
Error: function 'event_handler.onKeyEvent' is nothrow yet may 
throw


The compiler wouldn't let me just remove "nothrow" from the 
function. I tried a kludge where I had this function just pass 
all its parameters to another throwable function, but this caused 
errors as well.

So I'm stuck.  Anyone know how to proceed.
Thanks.
Oct 31 2016
next sibling parent reply Temtaime <temtaime gmail.com> writes:
On Monday, 31 October 2016 at 16:55:51 UTC, WhatMeWorry wrote:
 Is there a way to turn off nothrow or work around it? Because 
 to me it looks like nothrow prevents me from doing anything 
 useful.

 extern(C) void onKeyEvent(GLFWwindow* window, int key, int 
 scancode, int action, int modifier) nothrow
 {
     if(queue.roomInQueue())
     {
         auto event = new Event;
         event.type = EventType.keyboard;
         event.keyboard.key = cast(Key) key;

         // etc.
 }

 Error: function 'event_handler.CircularQueue.roomInQueue' is 
 not nothrow
 Error: function 'event_handler.onKeyEvent' is nothrow yet may 
 throw


 The compiler wouldn't let me just remove "nothrow" from the 
 function. I tried a kludge where I had this function just pass 
 all its parameters to another throwable function, but this 
 caused errors as well.

 So I'm stuck.  Anyone know how to proceed.
 Thanks.
Wrap a body of the function to try {} catch {} and it'll work.
Oct 31 2016
parent reply Kapps <opantm2+spam gmail.com> writes:
On Monday, 31 October 2016 at 17:04:28 UTC, Temtaime wrote:
 On Monday, 31 October 2016 at 16:55:51 UTC, WhatMeWorry wrote:
 Is there a way to turn off nothrow or work around it? Because 
 to me it looks like nothrow prevents me from doing anything 
 useful.

 extern(C) void onKeyEvent(GLFWwindow* window, int key, int 
 scancode, int action, int modifier) nothrow
 {
     if(queue.roomInQueue())
     {
         auto event = new Event;
         event.type = EventType.keyboard;
         event.keyboard.key = cast(Key) key;

         // etc.
 }

 Error: function 'event_handler.CircularQueue.roomInQueue' is 
 not nothrow
 Error: function 'event_handler.onKeyEvent' is nothrow yet may 
 throw


 The compiler wouldn't let me just remove "nothrow" from the 
 function. I tried a kludge where I had this function just pass 
 all its parameters to another throwable function, but this 
 caused errors as well.

 So I'm stuck.  Anyone know how to proceed.
 Thanks.
Wrap a body of the function to try {} catch {} and it'll work.
Assuming you're sure it'll never throw. To enforce this, use try { } catch { throw new Error("blah"); }. You can still throw errors, just not exceptions (as errors are not meant to be caught).
Oct 31 2016
next sibling parent reply Jonathan M Davis via Digitalmars-d-learn writes:
On Monday, October 31, 2016 22:20:59 Kapps via Digitalmars-d-learn wrote:
 Assuming you're sure it'll never throw. To enforce this, use try
 { } catch { throw new Error("blah"); }. You can still throw
 errors, just not exceptions (as errors are not meant to be
 caught).
I always use assert(0). e.g. try return format("%s", 42); catch(Exception) assert(0, "format threw when it shouldn't be possible."); - Jonathan M Davis
Oct 31 2016
next sibling parent Daniel9 <andreikovalsa mail.ru> writes:
On Monday, 31 October 2016 at 22:29:19 UTC, Jonathan M Davis 
wrote:
 On Monday, October 31, 2016 22:20:59 Kapps via 
 Digitalmars-d-learn wrote:
 Assuming you're sure it'll never throw. To enforce this, use 
 try
 { } catch { throw new Error("blah"); }. You can still throw
 errors, just not exceptions (as errors are not meant to be
 caught).
I always use assert(0). e.g. try return format("%s", 42); catch(Exception) assert(0, "format threw when it shouldn't be possible."); - Jonathan M Davis
have the same problem
Nov 01 2016
prev sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 10/31/16 6:29 PM, Jonathan M Davis via Digitalmars-d-learn wrote:
 On Monday, October 31, 2016 22:20:59 Kapps via Digitalmars-d-learn wrote:
 Assuming you're sure it'll never throw. To enforce this, use try
 { } catch { throw new Error("blah"); }. You can still throw
 errors, just not exceptions (as errors are not meant to be
 caught).
I always use assert(0). e.g. try return format("%s", 42); catch(Exception) assert(0, "format threw when it shouldn't be possible.");
This turns into a non-printing seg fault when compiled in release mode. Is there not some assumeNoThrow wrapper somewhere? -Steve
Nov 01 2016
parent reply Jonathan M Davis via Digitalmars-d-learn writes:
On Tuesday, November 01, 2016 10:57:38 Steven Schveighoffer via Digitalmars-
d-learn wrote:
 On 10/31/16 6:29 PM, Jonathan M Davis via Digitalmars-d-learn wrote:
 On Monday, October 31, 2016 22:20:59 Kapps via Digitalmars-d-learn 
wrote:
 Assuming you're sure it'll never throw. To enforce this, use try
 { } catch { throw new Error("blah"); }. You can still throw
 errors, just not exceptions (as errors are not meant to be
 caught).
I always use assert(0). e.g. try return format("%s", 42); catch(Exception) assert(0, "format threw when it shouldn't be possible.");
This turns into a non-printing seg fault when compiled in release mode.
I'm well aware of that, and I don't see that as a problem. A message might be nice, but the key thing is that it kills the program if there's a problem, and given Mike's point about the C layer, having it segfault is potentially preferable to throwing an Error to kill the program.
 Is there not some assumeNoThrow wrapper somewhere?
Someone added assemWontThrow to std.exception semi-recently, but I'd be very surprised if it didn't incur performance overhead such that I'd just as soon use an explicit try-catch and be done with it. - Jonathan M Davis
Nov 01 2016
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 11/1/16 11:54 AM, Jonathan M Davis via Digitalmars-d-learn wrote:
 On Tuesday, November 01, 2016 10:57:38 Steven Schveighoffer via Digitalmars-
 d-learn wrote:
 On 10/31/16 6:29 PM, Jonathan M Davis via Digitalmars-d-learn wrote:
     assert(0, "format threw when it shouldn't be possible.");
This turns into a non-printing seg fault when compiled in release mode.
I'm well aware of that, and I don't see that as a problem. A message might be nice, but the key thing is that it kills the program if there's a problem, and given Mike's point about the C layer, having it segfault is potentially preferable to throwing an Error to kill the program.
I disagree that avoiding the message printing is not a problem. I have had the unpleasant experience of having a program that dies on the order of 1-2 weeks with "SegFault", without any way of instrumenting the failure (debugging not an option, doesn't fail on dev machine). Just a tiny hint of what the problem is, can save weeks if not months of searching. A little while ago, I added an internal tool to both abort a program, and print a message (including file and line number) to druntime. It's not exactly public, but may be useful to expose. It should be callable from any location, including signal handlers. https://github.com/dlang/druntime/blob/master/src/core/internal/abort.d
 Is there not some assumeNoThrow wrapper somewhere?
Someone added assemWontThrow to std.exception semi-recently, but I'd be very surprised if it didn't incur performance overhead such that I'd just as soon use an explicit try-catch and be done with it.
The function I'm imagining shouldn't add any overhead... -Steve
Nov 01 2016
parent reply Jonathan M Davis via Digitalmars-d-learn writes:
On Tuesday, November 01, 2016 12:19:11 Steven Schveighoffer via Digitalmars-
d-learn wrote:
 On 11/1/16 11:54 AM, Jonathan M Davis via Digitalmars-d-learn wrote:
 On Tuesday, November 01, 2016 10:57:38 Steven Schveighoffer via
 Is there not some assumeNoThrow wrapper somewhere?
Someone added assemWontThrow to std.exception semi-recently, but I'd be very surprised if it didn't incur performance overhead such that I'd just as soon use an explicit try-catch and be done with it.
The function I'm imagining shouldn't add any overhead...
assumeWontThrow uses lazy to do what it does (and I'm not sure that there's any other way to do it other than string mixins), and as I understand it, lazy isn't exactly efficient. Given that it always calls the resulting delegate though, the optimizer may be able to remove the extra cost. - Jonathan M Davis
Nov 01 2016
parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 11/1/16 12:24 PM, Jonathan M Davis via Digitalmars-d-learn wrote:
 On Tuesday, November 01, 2016 12:19:11 Steven Schveighoffer via Digitalmars-
 d-learn wrote:
 On 11/1/16 11:54 AM, Jonathan M Davis via Digitalmars-d-learn wrote:
 On Tuesday, November 01, 2016 10:57:38 Steven Schveighoffer via
 Is there not some assumeNoThrow wrapper somewhere?
Someone added assemWontThrow to std.exception semi-recently, but I'd be very surprised if it didn't incur performance overhead such that I'd just as soon use an explicit try-catch and be done with it.
The function I'm imagining shouldn't add any overhead...
assumeWontThrow uses lazy to do what it does (and I'm not sure that there's any other way to do it other than string mixins), and as I understand it, lazy isn't exactly efficient. Given that it always calls the resulting delegate though, the optimizer may be able to remove the extra cost.
I was thinking something like this: auto assumeNoThrow(alias foo, Args...)(Args args) nothrow { try { return foo(args); } catch(Exception e) { throw new Error("foo should not have done that!"); } } -Steve
Nov 01 2016
prev sibling parent Mike Parker <aldacron gmail.com> writes:
On Monday, 31 October 2016 at 22:20:59 UTC, Kapps wrote:

 Wrap a body of the function to try {} catch {} and it'll work.
Assuming you're sure it'll never throw. To enforce this, use try { } catch { throw new Error("blah"); }. You can still throw errors, just not exceptions (as errors are not meant to be caught).
Not advisable in this case. This is for a function intended to be used as a C callback. There's no guarantee any errors thrown will propagate through the C side back into the D side. I wrote an article about this on gamedev.net [1] a while back. The feedback there is what led me to finally declare all of the callback types in Derelict (like the GLFW key callback above) as nothrow. I've since refined my approach, but, unless things have changes significantly (and I don't believe they have) the general idea still holds. [1] http://www.gamedev.net/page/resources/_/technical/general-programming/d-exceptions-and-c-callbacks-r3323
Nov 01 2016
prev sibling parent Mike Parker <aldacron gmail.com> writes:
On Monday, 31 October 2016 at 16:55:51 UTC, WhatMeWorry wrote:
 Is there a way to turn off nothrow or work around it? Because 
 to me it looks like nothrow prevents me from doing anything 
 useful.

 extern(C) void onKeyEvent(GLFWwindow* window, int key, int 
 scancode, int action, int modifier) nothrow
 {
     if(queue.roomInQueue())
     {
         auto event = new Event;
         event.type = EventType.keyboard;
         event.keyboard.key = cast(Key) key;

         // etc.
 }

 Error: function 'event_handler.CircularQueue.roomInQueue' is 
 not nothrow
 Error: function 'event_handler.onKeyEvent' is nothrow yet may 
 throw


 The compiler wouldn't let me just remove "nothrow" from the 
 function. I tried a kludge where I had this function just pass 
 all its parameters to another throwable function, but this 
 caused errors as well.

 So I'm stuck.  Anyone know how to proceed.
 Thanks.
If you can't change the interface of CiricularQueue to be nothrow and don't want to wrap everything in a try...catch block, then just use a dynamic array. You can also use the old C union trick to avoid the need to allocate every event. That's the same thing SDL does. Something like this: ``` enum EventType { key, mouse, } struct KeyEvent { EventType type; ... this(...) { this.type = EventType.key; ... } } struct MouseEvent { EventType type; ... this(...) { this.type = EventType.mouse; ... } } union Event { EventType type; KeyEvent key; MouseEvent mouse; } Event[] eventq; extern(C) void onKeyEvent(GLFWwindow* window, int key, int scancode, int action, int modifier) nothrow { Event event; event.key = KeyEvent(window, key, scancode, action, modifier); eventq ~= event; } ```
Oct 31 2016