Discussion:
'this' parameter in virtual function calls
(too old to reply)
Sousuke
2009-12-30 06:36:25 UTC
Permalink
Hi VC++ compiler hackers,

I'd like to know how the compiler passes the 'this' parameter in
virtual function calls. To illustrate:

class Employee
{
public:
Employee(const string& name);
~Employee();

// Accessor
const string& GetName() const;

// Increases the salary of this employee by a given percent.
// Since different kinds of employees have different salaries,
// we leave this to be implemented for each kind of employee.
// (Sorry, I couldn't think of a better real-world example use
// of virtual functions :)
virtual void IncreaseSalary(int percent) = 0;

private:
// ...
};

// An example kind-of employee
class Manager : public Employee
{
public:
Manager(const string& name);
~Manager();

void IncreaseSalary(int percent);

private:
// ...
};

void f(Employee& employee)
{
printf("%s\n", employee.GetName().c_str());
employee.IncreaseSalary(50);
}

My understanding is that, for the 'employee.GetName()' call, the
compiler has mangled Employee::GetName into an ordinary function name
(e.g., Employee__GetName), and the 'employee' object is passed as a
hidden argument as the 'this' paramenter.

But what's happening for the 'employee.IncreaseSalary(50)' call? What
exactly is being passed as the 'this' parameter? The only thing I can
imagine is that the 'employee' object must somehow be converted to an
object of a derived class (such as Manager). But how? The compiler
doesn't even know what's the subclass of this particular Employee,
does it?
David Lowndes
2009-12-30 09:42:06 UTC
Permalink
Post by Sousuke
But what's happening for the 'employee.IncreaseSalary(50)' call? What
exactly is being passed as the 'this' parameter? The only thing I can
imagine is that the 'employee' object must somehow be converted to an
object of a derived class (such as Manager).
It doesn't work that way.

Each classes virtual function is accessed through a lookup table in
the instance of the class object. That way given the class instance
pointer (this), the compiler indirects the call through the virtual
function table to call the appropriate method for the derived class.

Dave
Stephan T. Lavavej [MSFT]
2010-01-04 19:24:45 UTC
Permalink
It's important to note that each polymorphic object stores a *pointer* to a
virtual function table. There is one pointer per object and one table per
class (until you get into more complicated inheritance scenarios, but tables
are never stored in objects). This is a common point of confusion.

STL
Post by David Lowndes
Post by Sousuke
But what's happening for the 'employee.IncreaseSalary(50)' call? What
exactly is being passed as the 'this' parameter? The only thing I can
imagine is that the 'employee' object must somehow be converted to an
object of a derived class (such as Manager).
It doesn't work that way.
Each classes virtual function is accessed through a lookup table in
the instance of the class object. That way given the class instance
pointer (this), the compiler indirects the call through the virtual
function table to call the appropriate method for the derived class.
Dave
Alex Blekhman
2009-12-30 10:02:54 UTC
Permalink
Post by Sousuke
Hi VC++ compiler hackers,
I'd like to know how the compiler passes the 'this' parameter in
virtual function calls.
In addition to David's answer. There is good article about
internal mechanics of VC++ compiler:

"C++: Under the Hood"
http://www.openrce.org/articles/files/jangrayhood.pdf

It is a bit old, but most of it is still relevant today.

Also, If you're really interested in the matter, I suggest you to
read the "Inside the C++ Object Model" by Stanley Lippman.

HTH
Alex
Igor Tandetnik
2009-12-30 14:22:35 UTC
Permalink
Post by Sousuke
But what's happening for the 'employee.IncreaseSalary(50)' call? What
exactly is being passed as the 'this' parameter? The only thing I can
imagine is that the 'employee' object must somehow be converted to an
object of a derived class (such as Manager). But how? The compiler
doesn't even know what's the subclass of this particular Employee,
does it?
IncreaseSalary, being a virtual method, is called indirectly though a pointer in the vtable. In the vtable for Employee subobject of Manager class, the entry for IncreaseSalary points to a small thunk that adjusts 'this' pointer from Employee* to Manager*, then jumps to Manager::IncreaseSalary.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. -- RFC 1925
Loading...