Sending an immutable object to a thread

anonymous via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Jul 24 12:28:34 PDT 2015


On Friday, 24 July 2015 at 18:55:26 UTC, Frank Pagliughi wrote:
> So then, of course, I hope/wonder/assume that the pointer to 
> the heap is sufficient to keep the heap memory alive, and that 
> this would be OK from the GC perspective to do something like 
> this:
>
>   B* make_b_thing(int i) { cast(B*) new B(i); }

(You missed a return there.)

I haven't followed the discussion, so I may be missing the point 
here. But if you're doing this so that the GC is aware of the 
`new`ed B, then you really don't need to. The GC has no problems 
with class types. Class references do keep objects alive.

That is, the above will not keep the created object any more 
alive than the following:

B make_b_thing(int i) { return new B(i); }

>
> That seems to work, but I guess I should try to force the 
> garbage collector to run to see if I can crash the program.
>
> ***BUT***: The really, really weird thing is that even though 
> you *think* that you have a pointer to a B object, you don't 
> really. Dereferencing is accepted by the compiler, but it plays 
> a nasty trick on you:

A B* is not a pointer to the memory of the object. It's a pointer 
to a class reference. The class reference itself, B, is a pointer 
to the memory of the object, under the hood.

Casting a B to B* makes as little sense as casting it to float* 
or char*.

>
>   B* p = make_b_thing(42);
>   writefln("Address of pointer: %s", p);
>
>   writefln("Value of i: %s", p.i);

p really is a pointer to the memory of the object. But by typing 
it B* you're stating that it's a pointer to a class reference, 
which is wrong.

p.i does two dereferences where one would be correct. First, p is 
dereferenced. The resulting data is really that of the object. 
But it's typed B, so the compiler thinks it's a class reference. 
So it takes first bytes of the actual object data, interprets it 
as a pointer, dereferences it, and assumes to see the object data 
there (wherever that is). Getting the i field of that garbage 
location results in some garbage data, of course.

>   writefln("Value of i: %s", (*p).i);

Same as above. When p is a pointer, then p.i becomes (*p).i 
automatically in D.

>   writefln("Value of i: %s", (cast(B)p).i);

Here the type has only one level of indirection, as it should be. 
And everything's fine.

>
> This compiles and runs fine, but produces:
>
>   Address of pointer: 7F7EE77CF020
>   Value of i: 4445040
>   Value of i: 4445040
>   Value of i: 42
>
> Maybe it's my C++ background talking, but that seems a bit 
> counter-intuitive.

I'd say it's your C++ background talking.


More information about the Digitalmars-d-learn mailing list