Jump to page: 1 2
Thread overview
make a nothrow call a throwing function
Feb 07, 2013
monarch_dodra
Feb 07, 2013
Jonathan M Davis
Feb 07, 2013
monarch_dodra
Feb 07, 2013
1100110
Feb 07, 2013
Maxim Fomin
Feb 07, 2013
monarch_dodra
Feb 07, 2013
Jonathan M Davis
Feb 07, 2013
monarch_dodra
Feb 08, 2013
Jonathan M Davis
Feb 08, 2013
Artur Skawina
Feb 08, 2013
Jonathan M Davis
Feb 08, 2013
monarch_dodra
Feb 08, 2013
Ali Çehreli
Feb 08, 2013
Artur Skawina
February 07, 2013
Is there any way that a nothrow function can call a function that throws, but without even trying to catch if an exception is thrown?

My use case is a pretty low level nothrow function, that needs to call something that never ever throws, but was not marked as such.

I want to avoid the "try/catch/[do nothing|assert]" because I don't want to pay for that. Ideally, i'd really just want to mark my function as nothrow, and have undefined behavior if it *does* throw.

Any way to do that?
February 07, 2013
On Thursday, February 07, 2013 11:06:14 monarch_dodra wrote:
> Is there any way that a nothrow function can call a function that throws, but without even trying to catch if an exception is thrown?
> 
> My use case is a pretty low level nothrow function, that needs to call something that never ever throws, but was not marked as such.
> 
> I want to avoid the "try/catch/[do nothing|assert]" because I don't want to pay for that. Ideally, i'd really just want to mark my function as nothrow, and have undefined behavior if it *does* throw.
> 
> Any way to do that?

You can cast the function.

- Jonathan M Davis
February 07, 2013
On Thursday, 7 February 2013 at 10:55:26 UTC, Jonathan M Davis wrote:
> On Thursday, February 07, 2013 11:06:14 monarch_dodra wrote:
>> Is there any way that a nothrow function can call a function that
>> throws, but without even trying to catch if an exception is
>> thrown?
>> 
>> My use case is a pretty low level nothrow function, that needs to
>> call something that never ever throws, but was not marked as such.
>> 
>> I want to avoid the "try/catch/[do nothing|assert]" because I
>> don't want to pay for that. Ideally, i'd really just want to mark
>> my function as nothrow, and have undefined behavior if it *does*
>> throw.
>> 
>> Any way to do that?
>
> You can cast the function.
>
> - Jonathan M Davis

Smart.

Unfortunatly, in this case, I'm trying to call "string.dup".

It would appear though that (apparently), dup is a property that returns a function pointer, or something. In any case, I can't seem to be able to get its address.

Now I feel kind of bad for suggesting banning taking the address of a property function ...

I can bypass this with a wrapper function I guess, but at this point, I'd have to bench to see if that is even worth it...
February 07, 2013
On 02/07/2013 05:38 AM, monarch_dodra wrote:
> On Thursday, 7 February 2013 at 10:55:26 UTC, Jonathan M Davis wrote:
>> On Thursday, February 07, 2013 11:06:14 monarch_dodra wrote:
>>> Is there any way that a nothrow function can call a function that
>>> throws, but without even trying to catch if an exception is
>>> thrown?
>>>
>>> My use case is a pretty low level nothrow function, that needs to
>>> call something that never ever throws, but was not marked as such.
>>>
>>> I want to avoid the "try/catch/[do nothing|assert]" because I
>>> don't want to pay for that. Ideally, i'd really just want to mark
>>> my function as nothrow, and have undefined behavior if it *does*
>>> throw.
>>>
>>> Any way to do that?
>>
>> You can cast the function.
>>
>> - Jonathan M Davis
>
> Smart.
>
> Unfortunatly, in this case, I'm trying to call "string.dup".
>
> It would appear though that (apparently), dup is a property that returns
> a function pointer, or something. In any case, I can't seem to be able
> to get its address.
>
> Now I feel kind of bad for suggesting banning taking the address of a
> property function ...
>
> I can bypass this with a wrapper function I guess, but at this point,
> I'd have to bench to see if that is even worth it...

scope(failure) has worked for me in the past, but mostly calling C functions from nothrow.

You do have to put it at the top of the function, but it's simple and nice.
February 07, 2013
On Thursday, 7 February 2013 at 11:38:29 UTC, monarch_dodra wrote:
> On Thursday, 7 February 2013 at 10:55:26 UTC, Jonathan M Davis wrote:
>> On Thursday, February 07, 2013 11:06:14 monarch_dodra wrote:
>>> Any way to do that?
>>
>> You can cast the function.
>>
>> - Jonathan M Davis
>
> Smart.
>
> Unfortunatly, in this case, I'm trying to call "string.dup".
>
> It would appear though that (apparently), dup is a property that returns a function pointer, or something. In any case, I can't seem to be able to get its address.
>
> Now I feel kind of bad for suggesting banning taking the address of a property function ...
>
> I can bypass this with a wrapper function I guess, but at this point, I'd have to bench to see if that is even worth it...

So, you want to call function (which throws) from function marked as nothrow? It seems to be breaking idea of what nothrow does.

You can do this in general by casting (which is preferred way) and by exploiting current holes/misspecified tricks/corner language cases which should be in general avoided. Unfortunately, it appears that you cannot cast in your particular case of array duplication. However there are other ways to break nothrow and you can use them (declaration mismatch, unions, delegates). I think the problem is not absence of ways of doing what you want, but in limitation of casting with respect to some properties of built-in types.

By the way, I would not say that dup array property cannot throw exceptions.
February 07, 2013
On Thursday, 7 February 2013 at 20:46:22 UTC, Maxim Fomin wrote:
> On Thursday, 7 February 2013 at 11:38:29 UTC, monarch_dodra wrote:
>> On Thursday, 7 February 2013 at 10:55:26 UTC, Jonathan M Davis wrote:
>>> On Thursday, February 07, 2013 11:06:14 monarch_dodra wrote:
>>>> Any way to do that?
>>>
>>> You can cast the function.
>>>
>>> - Jonathan M Davis
>>
>> Smart.
>>
>> Unfortunatly, in this case, I'm trying to call "string.dup".
>>
>> It would appear though that (apparently), dup is a property that returns a function pointer, or something. In any case, I can't seem to be able to get its address.
>>
>> Now I feel kind of bad for suggesting banning taking the address of a property function ...
>>
>> I can bypass this with a wrapper function I guess, but at this point, I'd have to bench to see if that is even worth it...
>
> So, you want to call function (which throws) from function marked as nothrow? It seems to be breaking idea of what nothrow does.
>
> You can do this in general by casting (which is preferred way) and by exploiting current holes/misspecified tricks/corner language cases which should be in general avoided. Unfortunately, it appears that you cannot cast in your particular case of array duplication. However there are other ways to break nothrow and you can use them (declaration mismatch, unions, delegates). I think the problem is not absence of ways of doing what you want, but in limitation of casting with respect to some properties of built-in types.
>
> By the way, I would not say that dup array property cannot throw exceptions.

In this particular case, in is an string dup, so it *should* be nothrow.

Still the final solution has is more problematic than anything, so I'll just try/catch.
February 07, 2013
On Thursday, February 07, 2013 21:46:21 Maxim Fomin wrote:
> So, you want to call function (which throws) from function marked as nothrow? It seems to be breaking idea of what nothrow does.

I believe that the problem is that the function isn't marked nothrow even though it doesn't throw. He essentially wants to be able to make the compiler treat it as nothrow at the call site (since he can't change the function definition) without any overhead, and I don't think that that's actually possible.

The normal way to handle cases where you know that a function won't throw but isn't nothrow is to wrap it in a try block and put an assert(0) statement in the catch block. That does incur some amound of overhead, but I don't know how much. Apparently, monarch_dodra thinks that it's too much for what he's doing though.

- Jonathan M Davis
February 07, 2013
On Thursday, 7 February 2013 at 21:32:28 UTC, Jonathan M Davis wrote:
> On Thursday, February 07, 2013 21:46:21 Maxim Fomin wrote:
>> So, you want to call function (which throws) from function marked
>> as nothrow? It seems to be breaking idea of what nothrow does.
>
> I believe that the problem is that the function isn't marked nothrow even
> though it doesn't throw. He essentially wants to be able to make the compiler
> treat it as nothrow at the call site (since he can't change the function
> definition) without any overhead, and I don't think that that's actually
> possible.

I was though able to get a function pointer, and cast said pointer, at compile time (place it an enum). At that point, calling the function via the compile-time known pointer *should* be just as efficient as calling the function directly. I'll need to check the assembly.

EG:

//----
import std.stdio;

void bar()
{writeln("bar");}

void foo() nothrow
{
    enum barnothrow = cast(void function() nothrow)(&bar);
    barnothrow();
}

void main()
{foo();}
//----

Yes, writeln actually can throw, so it's a bad example, but a proof. I'd be surprised if there was any run-time overhead (but I could be wrong).

In my case though, there is an extra overhead that I can't get a function pointer to dup, so I have to create an intermediary function. Depending on the inlined-ness of things, *that* may or may not incur an overhead.

> The normal way to handle cases where you know that a function won't throw but
> isn't nothrow is to wrap it in a try block and put an assert(0) statement in
> the catch block. That does incur some amound of overhead, but I don't know how
> much. Apparently, monarch_dodra thinks that it's too much for what he's doing
> though.
>
> - Jonathan M Davis

Well, I don't think it's too much, but wanted to know the alternatives. I like to know my options, and their costs. It costs nothing to ask, and you never know what you'll learn.

I think the conclusion I came to though is to bite the bullet, and not worry too about it.

Thank you for your answers anyways.
February 08, 2013
On Thursday, February 07, 2013 23:14:51 monarch_dodra wrote:
> I was though able to get a function pointer, and cast said pointer, at compile time (place it an enum). At that point, calling the function via the compile-time known pointer *should* be just as efficient as calling the function directly. I'll need to check the assembly.

Hmmm. I wouldn't have thought that you could get the function pointer at compiler time. Regardless, you lose any possibility of inlining the function call, which is the main problem AFAIK, though I don't know if they would have been an option in the case of dup anyway.

> I think the conclusion I came to though is to bite the bullet, and not worry too about it.

Well, long term, this should be solved by dup actually being nothrow when it can't throw.

- Jonathan M Davis
February 08, 2013
On 02/08/13 01:33, Jonathan M Davis wrote:
> Hmmm. I wouldn't have thought that you could get the function pointer at compiler time. Regardless, you lose any possibility of inlining the function call, which is the main problem AFAIK, though I don't know if they would have been an option in the case of dup anyway.

It doesn't affect inlining. (Obviously, that's compiler dependent, but there's no reason why it should and indeed does not w/ gdc)

artur
« First   ‹ Prev
1 2