Jump to page: 1 2
Thread overview
newbie problem with nothrow
Oct 31, 2016
WhatMeWorry
Oct 31, 2016
Temtaime
Oct 31, 2016
Kapps
Oct 31, 2016
Jonathan M Davis
Nov 01, 2016
Daniel9
Nov 01, 2016
Jonathan M Davis
Nov 01, 2016
Jonathan M Davis
Nov 01, 2016
Mike Parker
Nov 01, 2016
Mike Parker
October 31, 2016
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.

October 31, 2016
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.
October 31, 2016
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).
October 31, 2016
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

November 01, 2016
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;
}
```

November 01, 2016
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


November 01, 2016
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
November 01, 2016
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
November 01, 2016
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

November 01, 2016
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
« First   ‹ Prev
1 2