www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - 'this' in base class out contract

reply Michael Shulman <viritrilbia gmail.com> writes:
Why does the following code fail the assertion?

class A {
  void foo()
    out  { assert(stored is this); }
    body { }
}

A stored;

class B : A {
  void foo() { stored = this; }
}

void main () {
  B x = new B();
  x.foo();
}
Jun 04 2011
parent reply bearophile <bearophileHUGS lycos.com> writes:
Michael Shulman:

 Why does the following code fail the assertion?
I don't know the answer yet, but I suggest to generally compile your D code with the -w compiler switch. I have modified the code, the __gshared and the assert removal are to simplify the asm: import std.c.stdio: printf; class Klass1 { void foo() out { printf("Klass1.this: %x\n", cast(void*)this); printf("Klass1.stored: %x\n", cast(void*)stored); //assert(stored is this); } body {} } __gshared Klass1 stored; class Klass2 : Klass1 { override void foo() { printf("Klass2.this: %x\n", cast(void*)this); stored = this; } } void main () { Klass2 x = new Klass2(); printf("x: %x\n", cast(void*)x); x.foo(); } Output: x: 14e2fd0 Klass2.this: 14e2fd0 Klass1.this: 41d1b0 Klass1.stored: 14e2fd0 I have compiled it with (dmd 2.053): dmd -O The asm: _D4test6Klass13fooMFZv comdat L0: push EBP mov EBP,ESP sub ESP,018h mov -018h[EBP],EAX call near ptr _D9invariant12_d_invariantFC6ObjectZv lea EAX,-018h[EBP] call near ptr _D4test6Klass13fooMFZv8__ensureMFZv mov ESP,EBP pop EBP ret _D4test6Klass13fooMFZv8__ensureMFZv comdat L0: push EAX mov ECX,offset FLAT:_DATA push dword ptr [EAX] push ECX call near ptr _printf mov EAX,offset FLAT:_DATA[014h] push dword ptr _D4test6storedC4test6Klass1 push EAX call near ptr _printf add ESP,010h pop EAX ret _D4test6Klass23fooMFZv comdat L0: push EBP mov EBP,ESP sub ESP,014h push EBX mov EBX,EAX call near ptr _D9invariant12_d_invariantFC6ObjectZv mov EAX,offset FLAT:_D4test6Klass16__vtblZ[01Ch] push EBX push EAX call near ptr _printf mov EAX,EBX mov _D4test6storedC4test6Klass1,EBX call near ptr _D4test6Klass13fooMFZv8__ensureMFZv add ESP,8 pop EBX mov ESP,EBP pop EBP ret __Dmain comdat L0: push EBX mov EAX,offset FLAT:_D4test6Klass27__ClassZ push EAX call near ptr __d_newclass add ESP,4 mov ECX,offset FLAT:_D4test6Klass26__vtblZ[01Ch] push EAX mov EBX,EAX push ECX call near ptr _printf mov EDX,[EBX] mov EAX,EBX call dword ptr 018h[EDX] add ESP,8 xor EAX,EAX pop EBX ret Bye, bearophile
Jun 04 2011
parent reply bearophile <bearophileHUGS lycos.com> writes:
 x: 14e2fd0
 Klass2.this: 14e2fd0
 Klass1.this: 41d1b0
 Klass1.stored: 14e2fd0
Note how much different are the two values of the object references. They may even be in two different kinds of memory. Klass1.this may be in the static segment instead of the heap :-) Bye, bearophile
Jun 04 2011
parent Michael Shulman <viritrilbia gmail.com> writes:
On Sat, Jun 4, 2011 at 4:27 AM, bearophile <bearophileHUGS lycos.com> wrote:
 x: 14e2fd0
 Klass2.this: 14e2fd0
 Klass1.this: 41d1b0
 Klass1.stored: 14e2fd0
Note how much different are the two values of the object references. They may even be in two different kinds of memory. Klass1.this may be in the static segment instead of the heap :-)
Why would that be?
Jun 04 2011