On Sunday, 12 May 2013 at 18:21:14 UTC, SundayMorningRunner wrote:
On Sunday, 12 May 2013 at 18:14:51 UTC, Maxim Fomin wrote:
On Sunday, 12 May 2013 at 17:31:22 UTC, SundayMorningRunner
wrote:
Hello, let's say I have the choice between using an abstract
class or an interface to declare a "plan", a "template" for
the descendants.
From the dmd compiler point of view, should I use the
abstract class version (so I guess that for each method call,
there will be a few MOV, in order to extract the relative
address from the vmt before a CALL) or the interface version
(are the CALL directly performed in this case). Are interface
faster ? (to get the address used by the CALL).
Thx.
I doubt that looking from buggy compiler POV is a good idea.
Anyway you can take code and look into assembly.
Which is exactly what you could have done before answering ;)
This is exactly what I *have done* before answering to get
correct answer for me. I see no reasons to ask such questions if
you can do the test yourself.
interface I
{
void foo();
}
class A : I { void foo(){}}
abstract class B { void foo() {} }
class C : B {}
void bar(C c, I i)
{
c.foo();
i.foo();
}
void main()
{
A a = new A;
a.foo();
C c = new C;
c.foo();
bar(c, a);
}
disas _Dmain
Dump of assembler code for function _Dmain:
0x0000000000419cd8 <+0>: push %rbp
0x0000000000419cd9 <+1>: mov %rsp,%rbp
0x0000000000419cdc <+4>: sub $0x10,%rsp
0x0000000000419ce0 <+8>: movabs $0x639210,%rdi
0x0000000000419cea <+18>: callq 0x41becc <_d_newclass>
0x0000000000419cef <+23>: mov %rax,-0x10(%rbp)
0x0000000000419cf3 <+27>: mov %rax,%rdi
0x0000000000419cf6 <+30>: mov (%rax),%rcx
0x0000000000419cf9 <+33>: rex.W callq *0x28(%rcx)
0x0000000000419cfd <+37>: movabs $0x639380,%rdi
0x0000000000419d07 <+47>: callq 0x41becc <_d_newclass>
0x0000000000419d0c <+52>: mov %rax,-0x8(%rbp)
0x0000000000419d10 <+56>: mov %rax,%rdi
0x0000000000419d13 <+59>: mov (%rax),%rdx
0x0000000000419d16 <+62>: rex.W callq *0x28(%rdx)
0x0000000000419d1a <+66>: mov -0x8(%rbp),%rsi
0x0000000000419d1e <+70>: cmpq $0x0,-0x10(%rbp)
0x0000000000419d23 <+75>: je 0x419d2f <_Dmain+87>
0x0000000000419d25 <+77>: mov -0x10(%rbp),%rax
0x0000000000419d29 <+81>: lea 0x10(%rax),%rdi
0x0000000000419d2d <+85>: jmp 0x419d32 <_Dmain+90>
0x0000000000419d2f <+87>: xor %rdi,%rdi
---Type <return> to continue, or q <return> to quit---
0x0000000000419d32 <+90>: callq 0x419cb0
<_D4main3barFC4main1CC4main1IZv>
0x0000000000419d37 <+95>: xor %eax,%eax
0x0000000000419d39 <+97>: leaveq
0x0000000000419d3a <+98>: retq
End of assembler dump.
disas _D4main3barFC4main1CC4main1IZv
Dump of assembler code for function
_D4main3barFC4main1CC4main1IZv:
0x0000000000419cb0 <+0>: push %rbp
0x0000000000419cb1 <+1>: mov %rsp,%rbp
0x0000000000419cb4 <+4>: sub $0x10,%rsp
0x0000000000419cb8 <+8>: mov %rdi,-0x10(%rbp)
0x0000000000419cbc <+12>: mov %rsi,%rdi
0x0000000000419cbf <+15>: mov (%rsi),%rax
0x0000000000419cc2 <+18>: rex.W callq *0x28(%rax)
0x0000000000419cc6 <+22>: mov -0x10(%rbp),%rdi
0x0000000000419cca <+26>: mov (%rdi),%rcx
0x0000000000419ccd <+29>: rex.W callq *0x8(%rcx)
0x0000000000419cd1 <+33>: leaveq
0x0000000000419cd2 <+34>: retq
End of assembler dump.