On Tuesday, 29 March 2016 at 06:21:49 UTC, Ali Çehreli wrote:
parent.prep.bind is translated to the following by the compiler:
"Call bind() for the object at address... let's calculate...
Wherever parent is, we should add the offset of prep inside
that object."
Okay, that's helpful actually. So, when accessing members of an
object, it won't trigger a NPE, because the object is not
dereferenced immediately, but the expected offset to the member
is dereferenced. D puts off resolving pointer addresses as much
as possible, so instead of bind((*parent).(*prep)) it's more like
bind(parentlocation + prepoffset) and only (this.)member resolves
to (*(parentlocation + prepoffset).member).
I thought it had an extra layer of pointer indirection, like if
class object A has address 1234, and member A.b has offset 0x20,
then you first dereference address 1234 (to get 4321 say) and
then add 0x20 to that. But actually a class object is... already
dereferenced, and is an integer representing the address to the
object, not a pointer to that address.
Variables representing fixed, definite memory locations really
throws me sometimes. You can't assign to a const, because that
assigns to const marked memory, and doesn't just move the
variable somewhere else. And NPE doesn't occur with a class,
because setting it to NULL, and accessing a member is more like
this in C:
intptr_t a = 0;
(struct B*)(a+0x20).member
and less like this in C:
intptr_t* a = 0;
(struct B*)(*a+0x20).member