pointers, functions, and uniform call syntax

Artur Skawina art.08.09 at gmail.com
Thu Sep 6 15:00:51 PDT 2012


On 09/06/12 18:21, Iain Buclaw wrote:
> On 6 September 2012 11:58, Artur Skawina <art.08.09 at gmail.com> wrote:
>> On 09/06/12 12:29, Artur Skawina wrote:
>>>    class C { int i; auto f() { return i; } }
>>>    int main() {
>>>       C c;
>>>       return c.f();
>>>    }
>>>
>>> Here you won't even get an assert error, just a segfault. But the pointer-to-class
>>
>> Argh. The reason you won't get get an assert is because I forgot to add
>> 'final' when converting the struct example...
>>
>>    class C { int i; final f() { return i; } }
>>    int main() {
>>       C c;
>>       return c.f();
>>    }
>>
>>
>> BTW, why doesn't GDC figure this out by itself? IIRC GCC gets these
>> cases right both for C++ and C (!), but does not devirtualize D methods,
>> not even in LTO/WPR mode...
> 
> All methods are virtual by default in D.  If you feel there is
> something that can be improved in GDC's codegen, please send a
> testcase and a written example of the behaviour it should show, and I
> will look into it. :-)

I'm just wondering /why/ the optimization doesn't happen for D; there
are far more important issues like cross-module inlining. Eventually 
devirtualization will be needed exactly because all methods are virtual.

The test case would be something like the following two programs:

C++: 
   class C {
      public:
      virtual int foo(int i) { return i+1; }
   };

   int main() {
      C* c = new C;
      int i = 0;
      i = c->foo(i);
      return i;
   }

D:
   class C {
      int foo(int i) { return i+1; }
   };

   int main() {
      C c = new C;
      int i = 0;
      i = c.foo(i);
      return i;
   }

The first compiles to:

 8048420:       83 ec 04                sub    $0x4,%esp
 8048423:       c7 04 24 04 00 00 00    movl   $0x4,(%esp)
 804842a:       e8 e1 ff ff ff          call   8048410 <_Znwj at plt>
 804842f:       c7 00 a0 85 04 08       movl   $0x80485a0,(%eax)
 8048435:       b8 01 00 00 00          mov    $0x1,%eax
 804843a:       83 c4 04                add    $0x4,%esp
 804843d:       c3                      ret    

but the second results in:

 8049820:       55                      push   %ebp
 8049821:       89 e5                   mov    %esp,%ebp
 8049823:       83 ec 18                sub    $0x18,%esp
 8049826:       c7 04 24 c0 47 07 08    movl   $0x80747c0,(%esp)
 804982d:       e8 0e 4d 00 00          call   804e540 <_d_newclass>
 8049832:       8b 10                   mov    (%eax),%edx
 8049834:       c7 44 24 04 00 00 00    movl   $0x0,0x4(%esp)
 804983b:       00 
 804983c:       89 04 24                mov    %eax,(%esp)
 804983f:       ff 52 18                call   *0x18(%edx)
 8049842:       c9                      leave  
 8049843:       c3                      ret    

ie in the D version the call isn't devirtualized.

artur


More information about the Digitalmars-d mailing list