On this page

Virtual functions under the hood

Ads

Navigation

Search

Categories

Clouds

Sql Server (5) .Net (16) .Net 2.0 (2) C# (3) @ff Topic (5) Architectural solutions (9) ASP (1) BDD (5) Blog related (8) database (2) Development process (8) Facebook (1) job interviews (1) Lessons (5) Life (12) Microsoft (5) IIS 6 (2) SPS (sharepoint server) (3) Drivers (1) Internet Explorer (2) Windows 2003 server (1) NightDuck (2) Performance (5) Security (9) Sql Server 2000 (4) Study (2) TDD (1) Threading (3) Under the hood (1) Web (1) Web services (1) XSS (6)

Archive

Blogroll

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

RSS 2.0 | Atom 1.0 | CDF

Send mail to the author(s) E-mail

Total Posts: 63
This Year: 0
This Month: 0
This Week: 0
Comments: 33

Sign In
Pick a theme:

 Saturday, July 21, 2007
Saturday, July 21, 2007 1:39:10 PM (GMT Standard Time, UTC+00:00) ( .Net | job interviews | Under the hood )

a little background to that question,
in the last week I'm doing some sort of a job interviews marathon, being asked for some quite interesting questions (most of them are really simply OPP questions).
but this one caught me off guard, wouldn't expect this one as a pre-interview question over the phone.

so, how does this strange creature work (which most of us using it without even knowing what it does behind) ?

in contrast to regular method calling, the virtual method calling isn't called directly, instead it uses the "Virtual Functions Table". (C# compiler implements it with VFT, other compilers may implement it via binary trees)
in short, it uses pointers to functions table, to map the call to the right method.
lets take a look at an example :

public class Father
{
public virtual void foo()
{
Console.Write("string from the father");
}

public virtual void foo2()
{
Console.Write("foo2 string from the father");
}

internal void boo()
{
Console.Write("father says boo");
}
}

public class Son : Father
{
public override void foo()
{
Console.Write("string from the son");
}
public void moo()
{
Console.Write("son says moo");
}
public void faaBase()
{
base.foo();
}
}

we have 2 classes ,son derives from the father, and overrides one of his virtual methods.

Father f = new Father();
Son s = new Son();

// Father calls
// Virtual method call
f.foo();
f.foo2();

// Non virtual method calls
f.boo();

// Son calls
// Virtual method call
s.foo();

// Non virtual method calls
s.boo();
s.moo();

what really happens behind ?
lets view a part of the disassembly code

// Virtual method call
s.foo();
00000065 mov ecx,esi
00000067 mov eax,dword ptr [ecx]
00000069 call dword ptr [eax+38h]
0000006c nop

s.foo2();
0000006d mov ecx,esi
0000006f mov eax,dword ptr [ecx]
00000071 call dword ptr [eax+3Ch]
00000074 nop

// Non virtual method calls
s.boo();
00000075 mov ecx,esi
00000077 cmp dword ptr [ecx],ecx
00000079 call FFAB30A0
0000007e nop

s.moo();
0000007f mov ecx,esi
00000081 cmp dword ptr [ecx],ecx
00000083 call FFAB3158
00000088 nop


we can see clearly that the non virtual call has a direct calling to the function (a hard coded address),
whereas the virtual method calling points to the virtual method table that resides in the Son object.
lets take a look on that table :

EEClass: 00a21370
Module: 00a22c24
Name: VTF.Son
mdToken: 02000004 (E:\PROJECTS\vtf 2005\VTF\VTF\bin\Debug\VTF.exe)
BaseSize: 0xc
ComponentSize: 0x0
Number of IFaces in IFaceMap: 0
Slots in VTable: 9
--------------------------------------
MethodDesc Table
Entry    MethodDesc JIT     Name
7934cdcc 79137ab8    PreJIT System.Object.ToString()
7934bba0 79137ac0    PreJIT System.Object.Equals(System.Object)
7934bb90 79137ad8    PreJIT System.Object.GetHashCode()
793424c0 79137ae0    PreJIT System.Object.Finalize()
00a231b8 00a23140    JIT    VTF.Son.foo()
00a23100 00a23088    JIT    VTF.Father.foo2()

00a231c8 00a23148    NONE   VTF.Son.moo()
00a231d8 00a23150    NONE   VTF.Son.faaBase()
00a231e8 00a23158    JIT    VTF.Son..ctor()

 

we can see a couple of things from this table:

  • VT lists all the methods the son object holds
  • VT lists the virtual functions of the father that are virtual
  • When the son object overrides one of the virtual methods that the father implements,
    the father method entry is being replaced by the new son method (line 5 at the table - Son.foo())
  • the VT does not list father method that are not virtual.

actually the Son.moo() method looks a little unnecessary in the VT due to the fact that the function is not virtual and will be addressed directly and not by the VT.

in conclusion, think twice before you declare a method as virtual, because it contains some performance hit