Sending an immutable object to a thread

Frank Pagliughi via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Jul 23 06:48:00 PDT 2015


On Thursday, 23 July 2015 at 09:05:12 UTC, Marc Schütz wrote:
>
> It is not safe, but for a different reason: `mt` is already a 
> _reference_ to the actual object (that's how classes behave in 
> D). This reference is located in a register or on the stack, 
> and `&mt` is therefore a pointer into the stack.
>
> It's illegal to return that pointer from the function, because 
> it will become invalid once the function is left. Fortunately, 
> the compiler can detect simple cases like this one, and will 
> refuse to compile it:
>
>     Object* foo() {
>         Object o;
>         return &o;
>     }
>
> xx.d(3): Error: escaping reference to local o

Very interesting. You see, I am trying to resolve the distinction 
be a value type and a reference type in D.

If Object were declared as a "struct", this would make sense to 
me. The object would be created on the stack as a temporary, and 
it would disappear when the function exited. So returning a 
pointer to it would be a very, very bad thing.

But a class object is allocated in the GC heap. I would have 
guessed that, since a class reference is just essentially a 
hidden pointer, that the address-of operator '&' for a class 
object would return the address into the heap... not the address 
of the reference itself! Just a little syntactic sugar.

But that's not the case. I thought this was true:
   class MyThing { ... };

   MyThing a = new MyThing,
           b = a;
   assert(&a == &b);  // Fails

In a weird way, that makes total sense to me, and no sense at all.

So, passing a pointer to a stack-based reference from one thread 
is another is not necessarily a good thing to do, as the original 
reference might disappear while the thread is using it.

Is there a way to get the address of the actual heap object from 
a class reference? Or am I drifting to far into the realm of 
"unsafe".

This all goes back to my original question of passing an 
immutable object from one thread to another. It is simple with 
arrays, since there is a clear distinction between the array 
reference and its contents. You can easily create a mutable 
reference to immutable contents with an array.

But it seems rather convoluted with class objects.

So, in the end, it seems best to send a rebindable reference to 
the other thread, and perhaps hide the mild ugliness behind a 
library API that takes an immutable object and then sends the 
rebindable version, like:

   void send_message(Tid tid, immutable(Message) msg) {
     send(tid, thisTid(), rebindable(msg));
   }

That seems easy enough.

Thanks much for all the help.



More information about the Digitalmars-d-learn mailing list