On Saturday, 19 April 2014 at 23:44:45 UTC, Marco Leise wrote:
Am Wed, 16 Apr 2014 20:32:20 +0000
schrieb "Peter Alexander" <peter.alexander...@gmail.com>:

On Wednesday, 16 April 2014 at 20:29:17 UTC, bearophile wrote:
> Peter Alexander:
>
>> (I assume that nothrow isn't meant to be there?)
>
> In D nothrow functions can throw errors.

Of course, ignore me :-)


>> You could do something like this:
>>
>> void foo() @nogc
>> {
>>    static err = new Error();
>>    if (badthing)
>>    {
>>        err.setError("badthing happened");
>>        throw err;
>>    }
>> }
>
> To be mutable err also needs to be __gshared.

But then it isn't thread safe. Two threads trying to set and throw the same Error is a recipe for disaster.

Also: As far as I remember from disassembling C++, static
variables in functions are initialized on first access and
guarded by a bool. The first call to foo() would execute
"err = new Error();" in that case. This code should not
compile under @nogc.

D static initialization doesn't work the same way. Everything is initialized as the program is loaded, and everything must have a statically known value. EG: An Error is allocated *somewhere* (may or may not actually be the GC), and then the static value of the Error is a pointer to that.

It's what allows us to do things like:

class A{}

struct S
{
    A a = new A();
}

This is legal. All S.a will point the *same* A. S.init will be initialized to point to that a.

Also, just doing this is good enough:

//----
void foo() @nogc
{
   static err = new Error("badthing happened");
   if (badthing)
       throw err;
}
//----

It does require the message be known before hand, and not custom "built". But then again, where were you going to allocate the message, and if allocated, who would clean it up?

--------

That said, while the approach works, there could be issues with re-entrance, or chaining exceptions.

Reply via email to