how c++ compilers implement object orientation

28
How C++ Compilers Implement Object Orientation Eric Powders (ejp2127)

Upload: conan-cleveland

Post on 31-Dec-2015

22 views

Category:

Documents


1 download

DESCRIPTION

How C++ Compilers Implement Object Orientation. Eric Powders (ejp2127). Motivation. Couple years ago was asked in an interview, “How do Multiple Inheritance & Virtual Inheritance affect how a C++ compiler lays out class data?”. My thoughts were…. Well, I don’t know… - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: How C++ Compilers Implement Object Orientation

How C++ Compilers Implement Object Orientation

Eric Powders (ejp2127)

Page 2: How C++ Compilers Implement Object Orientation

Motivation

• Couple years ago was asked in an interview, “How do Multiple Inheritance & Virtual Inheritance affect how a C++ compiler lays out class data?”

2

Page 3: How C++ Compilers Implement Object Orientation

My thoughts were…

• Well, I don’t know…

• Actually, forget about MI/VI… how does the compiler lay out class data for “regular” inheritance?

• Actually, forget about inheritance… how does the compiler lay out class data for a simple class?

• Does it just lay out the data members in order?

• …Then how do singular inheritance, multiple inheritance, virtual inheritance affect this?

3

Page 4: How C++ Compilers Implement Object Orientation

Clearly I did not get that job…

• Later, went back & searched books & internet… couldn’t find answer to this anywhere!

• Realized I would need to do the research on my own using a compiler & manually hacking into the insides of objects

• Didn’t have time to do it then; glad I could finally look into this for class project now

• Used 2 compilers: gcc 4.5.2, MS Vis Std 2010

4

Page 5: How C++ Compilers Implement Object Orientation

Topics

• Basic class layout

• Inheritance

• Polymorphism: Virtual functions, vtables, vpointers

• Multiple Inheritance

• Virtual Inheritance (briefly)

• Dynamic casting (briefly)

5

Page 6: How C++ Compilers Implement Object Orientation

What is a class?

• Essentially a collection of data and functions branded with a new type, e.g.,:

class foo {

char a;

int b;

};

• Can now declare objects of type foo

• foo objects could occupy 5 bytes; might use 8

• If declared int then char, 5 bytes

• Address of object is addr of 1st data member6

Page 7: How C++ Compilers Implement Object Orientation

Inheritance

• Method of code reuse in which subclasses inherit some data and methods of their parent class.– Control what’s inherited via access rights

• Subclasses may override base class methods

• There may be multiple levels of inheritance– Having multiple levels of inheritance is not called multiple

inheritance

• Mult. levels of inh: each successive derived class inherits some of its parent's data and methods– Including “grandparents’” members, etc up the chain

7

Page 8: How C++ Compilers Implement Object Orientation

Warning: Next 2 slides are most important slides in the presentation

(they provide background & motivation for rest of presentation)

Page 9: How C++ Compilers Implement Object Orientation

Semantics of C++ Inheritance

• Assume base class B & derived class D

• We may then write:D foo; // create object of type D

B* bPtr = &foo; // base class ptr points at object

D* dPtr = &foo; // derived class ptr points at obj

• When using bPtr, compiler treats object as “type B” object; can only see members declared by B

• When using dPtr, compiler treats object as “type D” object; can access members declared by both B & D

9

Page 10: How C++ Compilers Implement Object Orientation

Why use bPtr if it’s so limiting?

• Can treat object of type B without having to worry about peculiarities of its depth

myFunction (vehicle* bPtr) // vehicle is base class

{bPtr -> startVehicle();}

• Can write code that works for B objs; later it will “just work” whenever pass in a derived obj– Even works for derived class created in few years!

• Won’t require recompilation• Requires compiler to lay out classes consistently to ensure

can locate members in future classes without recompilation

10

Page 11: How C++ Compilers Implement Object Orientation

Inheritance: Class Layout

• B = base class data; D = derived class data

• bPtr = base class ptr; dPtr = derived class ptr

11

Page 12: How C++ Compilers Implement Object Orientation

Inheritance: Class Layout

• For example, B has 2 data members: int, char• D declares addit data mem: string

• If we try to access the string via bPtr, compiler error

12

Page 13: How C++ Compilers Implement Object Orientation

Implementing polymorphism: Semantics of virtual functions

• virtual = invoke the func def appropriate for underlying obj, regardless of ptr type accessing obj with

• If accessing D obj (via bPtr or dPtr), use D’s func def if supplied; else use B’s func def

myFunction (vehicle* bPtr) // vehicle is base class

{bPtr -> startVehicle();}

• How can we compile myFunction if porsche.startVehicle() doesn’t exist yet?

13

Page 14: How C++ Compilers Implement Object Orientation

The vtable

• For every class with virtual func, compiler creates a vtable (abbrev: vtbl)

• vtbl holds an entry for every virt func, & addr of code to invoke func def

• Enables compiler to, at run-time, quickly find addr to invoke given a class name and func name

14

Page 15: How C++ Compilers Implement Object Orientation

D’s vtbl

• Assume B defines 3 virt funcs; D overrides v1 & v2 but not v3. D also defines a 4th virt func

• Compiler generates this when compiling D class:

v1 addr of D’s v1

v2 addr of D’s v2

v3 addr of B’s v3

v4 addr of D’s v4

• I think MS Vis Std stores this in array, while gcc stores in hash

15

Page 16: How C++ Compilers Implement Object Orientation

The vpointer

• Every object of a class with a vtbl holds a vpointer (abbrev: vptr), a ptr to class’s vtbl

• When compiler sees virt func, it finds obj’s vptr & follows to vtbl to locate addr of func to invoke

• As long as we put vptr in right spot, compiler can generate code now that invokes func that won’t be written for 3 years

• Compiler generates code that, given base class ptr, accesses obj’s vptr & looks up entries in vtbl

16

Page 17: How C++ Compilers Implement Object Orientation

Bottom line

• Of course the object's class and its vtbl don't have to be created for years into the future; as long as the compiler, at that future time, puts the new class object's vptr in a consistent location (which it should) and populates the vtbl consistently (which it should), code that was written and compiled long ago can still find and search the vtbl and dispatch function calls correctly.

17

Page 18: How C++ Compilers Implement Object Orientation

Where do we store the vptr?• Compiler must be able to, at compile time, generate code that

finds vptr even though won’t know obj type until run-time

• Thus vptr must reside inside B subobject

• More precisely: vptr must reside in “top-most” class that declares a virtual function

18

As long as compiler puts vptr here, will work when create new D class (porsche) in 3 yrs

Page 19: How C++ Compilers Implement Object Orientation

Semantics of Multiple Inheritance

• MI: derived class has multiple immediate "parents" (multiple immediate base classes).

• Example: class D that’s derived from 2 bases, B1 & B2.– D inherits data & methods from both B1 & B2– Same as with single inheritance: D may override any

of B1’s or B2’s methods– Further classes derived from D will inherit data &

methods from D, B1, & B2

19

Page 20: How C++ Compilers Implement Object Orientation

Example: 2 class hierarchies

• We’ll now create class DD inherited from both D1 & D2

20

Page 21: How C++ Compilers Implement Object Orientation

Per C++ language rules, different ways to handle DD obj:

B1* bPtr1 = new DD;

D1* dPtr1 = new DD;

B2* bPtr2 = new DD;

D2* dPtr2 = new DD;

DD* ddPtr = new DD;

• Compiler must access data & functions properly• Compiler must invoke proper version of virtual

functions21

Page 22: How C++ Compilers Implement Object Orientation

How should the compiler lay out DD's class data?

Page 23: How C++ Compilers Implement Object Orientation

• Quick overview• Key: must vet access

via all 5 ptrs• Access via bPtr1 (B1*)• Access via dPtr1 (D1*)• Access via bPtr2 (B2*)

– requires another vptr

• Access via dPtr2 (D2*)• They point into middle

of DD object!– bPtr1 & bPtr2 hold dft

addrs tho pt to same obj

• Access via ddPtr (DD*)23

Page 24: How C++ Compilers Implement Object Orientation

Semantics of virtual inheritance

• What if had this?– base class B1– 2 classes each directly derived from B1: D1 & D2– Class DD inherited from both D1 & D2

• Class DD now has 2 copies of base B1– 2 copies of each data member; can get very messy

• If use virtual inheritance, class DD only contains 1 copy of base B1 (per semantics of VI)– Opens a whole new can of worms

24

Page 25: How C++ Compilers Implement Object Orientation

Unfortunately would take too long to provide detailed explanation of how

compiler handles VI

(if interested, please read my report!)

Page 26: How C++ Compilers Implement Object Orientation

• Data layout: D1, D2, DD, B1

• Sole copy of B1 class data moved to end of obj

• D1 & D2 subobjects have ptr to B1 data

• Objects now have as many as 3 vptrs

• dPtr1, dPtr2, bPtr1 all point to dft addrs

• Explained in detail in my report! 26

Sneak peek…

Page 27: How C++ Compilers Implement Object Orientation

Due to time constraints, must skip over dynamic casting too…

• Dynamic casting: instructing compiler to reinterpret a pointer of 1 type as a pointer to another type in the same hierarchy

ddPtr = dynamic_cast<DD*> (bPtr1);

• Instructs compiler to reinterpret bPtr1 as if it were a ddPtr (of type DD*)

• Can be very complicated operation with MI/VI because ptrs point to different addrs in same obj!– Can dynamic_cast to type void* to determine the address of the

beginning of an object

• This is covered in my report as well

27

Page 28: How C++ Compilers Implement Object Orientation

In conclusion…

• Really glad I did this

• Feel like I really learned a lot

• Glad I could compare 2 compilers, & see that they mostly handle object orientation in similar fashion

• Questions?

28