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.

Reply via email to