Compiling OOP Features Swati Jaiswal Department of Computer Science and Engineering, Visvesvaraya National Institute of Technology, Nagpur Slides borrowed from Uday Khedker Department of Computer Science and Engineering, Indian Institute of Technology, Bombay July 2021 Part 1 Compiling OOP Features ACM Summer School on Compilers: Compiling OOP Features Outline • Internal representation of a class • Translating virtual function calls • Proposed optimization • Translating function template and class template Uday Khedker 1/23 ACM Summer School on Compilers: Compiling OOP Features Internal Representation of a Class class A { private: int x; int f2(int i) { return i+1;} public: int y,z; void f1(int i) { x = f2(i)*2;} }; a.f1(5); b.f1(10); Uday Khedker Data Memory Code Memory 2/23 ACM Summer School on Compilers: Compiling OOP Features Internal Representation of a Class class A { private: int x; int f2(int i) { return i+1;} public: int y,z; void f1(int i) { x = f2(i)*2;} }; A a; A b; a.f1(5); b.f1(10); Uday Khedker Data Memory Code Memory 2/23 ACM Summer School on Compilers: Compiling OOP Features 2/23 Internal Representation of a Class class A { private: int x; int f2(int i) { return i+1;} public: int y,z; void f1(int i) { x = f2(i)*2;} }; A a; A b; a.f1(5); b.f1(10); Uday Khedker x y z Object a x y z Object b Data Memory Code Memory void A::f1(struct A * const this , int i) { this-> x = A::f2(this, i)*2;} ThereA is*no int A::f2(struct const this, int i) between the { return distinction i+1;} public and private data in memory int main() ACM Summer School on Compilers: Compiling OOP Features 2/23 Internal Representation of a Class class A { private: int x; int f2(int i) { return i+1;} public: int y,z; void f1(int i) { x = f2(i)*2;} }; A a; A b; a.f1(5); b.f1(10); Uday Khedker x y z Every function with n parameters Object a is converted to a function of n + 1 x parameter y zwith the first parameter being the addressObject of thebobject Data Memory Code Memory void A::f1(struct A * const this , int i) { this-> x = A::f2(this, i)*2;} int A::f2(struct A * const this, int i) { return i+1;} int main() ACM Summer School on Compilers: Compiling OOP Features 2/23 Internal Representation of a Class class A { private: int x; int f2(int i) { return i+1;} public: int y,z; void f1(int i) { x = f2(i)*2;} }; A a; A b; a.f1(5); b.f1(10); Uday Khedker x y z Object a x y z Object b Data Memory Code Memory void A::f1(struct A * const this , int i) { this-> x = A::f2(this, i)*2;} int A::f2(struct A * const this, int i) { return i+1;} int main() { struct A a,b; A::f1 ( &a , 5); A::f1 ( &b , 10); } ACM Summer School on Compilers: Compiling OOP Features 2/23 Internal Representation of a Class class A { private: int x; int f2(int i) { return i+1;} public: int y,z; void f1(int i) { x = f2(i)*2;} }; A a; A b; a.f1(5); b.f1(10); Uday Khedker x y z Object a x y z Object b Data Memory Code Memory void A::f1(struct A * const this , int i) { this-> x = A::f2(this, i)*2;} int A::f2(struct A * const this, int i) { return i+1;} int main() { struct A a,b; A::f1 ( &a , 5); A::f1 ( &b , 10); } ACM Summer School on Compilers: Compiling OOP Features 2/23 Internal Representation of a Class class A { private: int x; int f2(int i) { return i+1;} public: int y,z; void f1(int i) { x = f2(i)*2;} }; A a; A b; a.f1(5); b.f1(10); Uday Khedker x y z Object a x y z Object b Data Memory Code Memory void A::f1(struct A * const this , int i) { this-> x = A::f2(this, i)*2;} int A::f2(struct A * const this, int i) { return i+1;} int main() { struct A a,b; A::f1 ( &a , 5); A::f1 ( &b , 10); } ACM Summer School on Compilers: Compiling OOP Features 2/23 Internal Representation of a Class class A { private: int x; int f2(int i) { return i+1;} public: int y,z; void f1(int i) { x = f2(i)*2;} }; A a; A b; a.f1(5); b.f1(10); Uday Khedker x 12 y x y z Object a z Object b Data Memory Code Memory void A::f1(struct A * const this , int i) { this-> x = A::f2(this, i)*2;} int A::f2(struct A * const this, int i) { return i+1;} int main() { struct A a,b; A::f1 ( &a , 5); A::f1 ( &b , 10); } ACM Summer School on Compilers: Compiling OOP Features 2/23 Internal Representation of a Class class A { private: int x; int f2(int i) { return i+1;} public: int y,z; void f1(int i) { x = f2(i)*2;} }; A a; A b; a.f1(5); b.f1(10); Uday Khedker x y z Object a x y z Object b Data Memory Code Memory void A::f1(struct A * const this , int i) { this-> x = A::f2(this, i)*2;} int A::f2(struct A * const this, int i) { return i+1;} int main() { struct A a,b; A::f1 ( &a , 5); A::f1 ( &b , 10); } ACM Summer School on Compilers: Compiling OOP Features 2/23 Internal Representation of a Class class A { private: int x; int f2(int i) { return i+1;} public: int y,z; void f1(int i) { x = f2(i)*2;} }; A a; A b; a.f1(5); b.f1(10); Uday Khedker x y z Object a x y z Object b Data Memory Code Memory void A::f1(struct A * const this , int i) { this-> x = A::f2(this, i)*2;} int A::f2(struct A * const this, int i) { return i+1;} int main() { struct A a,b; A::f1 ( &a , 5); A::f1 ( &b , 10); } ACM Summer School on Compilers: Compiling OOP Features 2/23 Internal Representation of a Class class A { private: int x; int f2(int i) { return i+1;} public: int y,z; void f1(int i) { x = f2(i)*2;} }; A a; A b; a.f1(5); b.f1(10); Uday Khedker x y z Object a x 22 y z Object b Data Memory Code Memory void A::f1(struct A * const this , int i) { this-> x = A::f2(this, i)*2;} int A::f2(struct A * const this, int i) { return i+1;} int main() { struct A a,b; A::f1 ( &a , 5); A::f1 ( &b , 10); } ACM Summer School on Compilers: Compiling OOP Features Padding Data and Computing Sizeof an Object class White { public: int w1; char w2; int w3; char w4; }; White w; Uday Khedker 0 4 8 12 w1 w2 w3 w4 size: 16 bytes 3/23 ACM Summer School on Compilers: Compiling OOP Features Padding Data and Computing Sizeof an Object class White { public: int w1; char w2; char w4; int w3; }; White w; Uday Khedker 0 4 8 12 w1 w2 w4 size: 12 bytes w3 4/23 ACM Summer School on Compilers: Compiling OOP Features Representing Inheritance of Data class White { public: int w1; }; class Blue : public White { public: int b1; int b2; }; class Pink : public Blue { public: int p1; int p2; }; White w; Blue b; Pink p; Uday Khedker w b w1 w1 b1 b2 p w1 b1 b2 p1 p2 5/23 ACM Summer School on Compilers: Compiling OOP Features Representing Inheritance of Data: Object Slicing class White { public: int w1; }; class Blue : public White { public: int b1; int b2; }; class Pink : public Blue { public: int p1; int p2; }; White w; Blue b; Pink p; Uday Khedker w b w1 w1 b1 b2 p w1 b1 b2 p1 p2 w=b 6/23 ACM Summer School on Compilers: Compiling OOP Features Representing Inheritance of Data: Object Slicing class White { public: int w1; }; class Blue : public White { public: int b1; int b2; }; class Pink : public Blue { public: int p1; int p2; }; White w; Blue b; Pink p; Uday Khedker w b w1 w1 b1 b2 p w1 b1 b2 p1 p2 w=b 6/23 ACM Summer School on Compilers: Compiling OOP Features Representing Inheritance of Data: Object Slicing class White { public: int w1; }; class Blue : public White { public: int b1; int b2; }; class Pink : public Blue { public: int p1; int p2; }; White w; Blue b; Pink p; Uday Khedker w b w1 w1 b1 b2 x p w1 b1 b2 p1 p2 w=b 6/23 ACM Summer School on Compilers: Compiling OOP Features Representing Inheritance of Data: Object Slicing class White { public: int w1; }; class Blue : public White { public: int b1; int b2; }; class Pink : public Blue { public: int p1; int p2; }; White w; Blue b; Pink p; Uday Khedker w b w1 w1 b1 b2 p w1 b1 b2 p1 p2 w=p 6/23 ACM Summer School on Compilers: Compiling OOP Features Representing Inheritance of Data: Object Slicing class White { public: int w1; }; class Blue : public White { public: int b1; int b2; }; class Pink : public Blue { public: int p1; int p2; }; White w; Blue b; Pink p; Uday Khedker w b w1 w1 b1 b2 p w1 b1 b2 p1 p2 w=p 6/23 ACM Summer School on Compilers: Compiling OOP Features Representing Inheritance of Data: Object Slicing class White { public: int w1; }; class Blue : public White { public: int b1; int b2; }; class Pink : public Blue { public: int p1; int p2; }; White w; Blue b; Pink p; Uday Khedker w b w1 w1 b1 b2 p w1 b1 b2 p1 p2 w=p 6/23 ACM Summer School on Compilers: Compiling OOP Features Representing Inheritance of Data: Object Slicing class White { public: int w1; }; class Blue : public White { public: int b1; int b2; }; class Pink : public Blue { public: int p1; int p2; }; White w; Blue b; Pink p; Uday Khedker w b w1 w1 b1 b2 p w1 b1 b2 p1 p2 b=p 6/23 ACM Summer School on Compilers: Compiling OOP Features Representing Inheritance of Data: Object Slicing class White { public: int w1; }; class Blue : public White { public: int b1; int b2; }; class Pink : public Blue { public: int p1; int p2; }; White w; Blue b; Pink p; Uday Khedker w b w1 w1 b1 b2 p w1 b1 b2 p1 p2 b=p 6/23 ACM Summer School on Compilers: Compiling OOP Features Representing Inheritance of Data: Object Slicing class White { public: int w1; }; class Blue : public White { public: int b1; int b2; }; class Pink : public Blue { public: int p1; int p2; }; White w; Blue b; Pink p; Uday Khedker w b w1 w1 b1 b2 p w1 b1 b2 p1 p2 x b=p 6/23 ACM Summer School on Compilers: Compiling OOP Features Representing Inheritance of Data: Object Slicing class White { public: int w1; }; class Blue : public White { public: int b1; int b2; }; class Pink : public Blue { public: int p1; int p2; }; White w; Blue b; Pink p; Uday Khedker w b w1 w1 b1 b2 p w1 b1 b2 p1 p2 b=w 6/23 ACM Summer School on Compilers: Compiling OOP Features Representing Inheritance of Data: Object Slicing class White { public: w int w1; w1 }; class Blue : public White b w1 { public: b1 int b1; b2 int b2; }; p class Pink : public Blue w1 { public: b1 int p1; b2 Error!! int p2; Base class does not include everything in the Derived class. p1 }; However, base class is contained in the Derived class. p2 White w; Blue b; Pink p; b=w Uday Khedker 6/23 ACM Summer School on Compilers: Compiling OOP Features Representing Inheritance of Data: Object Slicing class White { public: int w1; }; class Blue : public White { public: int b1; int b2; }; class Pink : public Blue { public: int p1; int p2; }; White *w; Blue b; Pink p; Uday Khedker w1 b w1 b1 b2 p w1 b1 b2 p1 p2 w = &b 7/23 ACM Summer School on Compilers: Compiling OOP Features Representing Inheritance of Data: Object Slicing class White { public: int w1; }; class Blue : public White { public: int b1; int b2; }; class Pink : public Blue { public: int p1; int p2; }; White *w; Blue b; Pink p; Uday Khedker w1 b w1 b1 b2 p w1 b1 b2 p1 p2 w = &b w 7/23 ACM Summer School on Compilers: Compiling OOP Features Representing Inheritance of Data: Object Slicing class White { public: int w1; }; class Blue : public White { public: int b1; int b2; }; class Pink : public Blue { public: int p1; int p2; }; White *w; Blue b; Pink p; Uday Khedker w1 b w1 b1 b2 x p w1 b1 b2 p1 p2 w = &b w 7/23 ACM Summer School on Compilers: Compiling OOP Features Representing Inheritance of Data: Object Slicing class White { public: int w1; }; class Blue : public White { public: int b1; int b2; }; class Pink : public Blue { public: int p1; int p2; }; White *w; Blue b; Pink p; Uday Khedker w1 b w1 b1 b2 p w1 b1 b2 p1 p2 w = &p 7/23 ACM Summer School on Compilers: Compiling OOP Features Representing Inheritance of Data: Object Slicing class White { public: int w1; }; class Blue : public White { public: int b1; int b2; }; class Pink : public Blue { public: int p1; int p2; }; White *w; Blue b; Pink p; Uday Khedker w1 b w1 b1 b2 p w1 b1 b2 p1 p2 w = &p w 7/23 ACM Summer School on Compilers: Compiling OOP Features Representing Inheritance of Data: Object Slicing class White { public: int w1; }; class Blue : public White { public: int b1; int b2; }; class Pink : public Blue { public: int p1; int p2; }; White *w; Blue b; Pink p; Uday Khedker w1 b w1 b1 b2 p w1 b1 b2 p1 p2 w = &p w 7/23 ACM Summer School on Compilers: Compiling OOP Features Representing Inheritance of Data: Object Slicing class White { public: int w1; }; class Blue : public White { public: int b1; int b2; }; class Pink : public Blue { public: int p1; int p2; }; White w; Blue *b; Pink p; Uday Khedker w w1 w1 b1 b2 p w1 b1 b2 p1 p2 b = &p 8/23 ACM Summer School on Compilers: Compiling OOP Features Representing Inheritance of Data: Object Slicing class White { public: int w1; }; class Blue : public White { public: int b1; int b2; }; class Pink : public Blue { public: int p1; int p2; }; White w; Blue *b; Pink p; Uday Khedker w w1 w1 b1 b2 p w1 b1 b2 p1 p2 b = &p b 8/23 ACM Summer School on Compilers: Compiling OOP Features Representing Inheritance of Data: Object Slicing class White { public: int w1; }; class Blue : public White { public: int b1; int b2; }; class Pink : public Blue { public: int p1; int p2; }; White w; Blue *b; Pink p; Uday Khedker w w1 w1 b1 b2 p w1 b1 b2 p1 p2 x b = &p b 8/23 ACM Summer School on Compilers: Compiling OOP Features Representing Inheritance of Data: Object Slicing class White { public: int w1; }; class Blue : public White { public: int b1; int b2; }; class Pink : public Blue { public: int p1; int p2; }; White w; Blue *b; Pink p; Uday Khedker w w1 w1 b1 b2 p w1 b1 b2 p1 p2 b = &w 8/23 ACM Summer School on Compilers: Compiling OOP Features Representing Inheritance of Data: Object Slicing class White { public: w int w1; w1 }; class Blue : public White w1 { public: b1 int b1; b2 int b2; }; p class Pink : public Blue w1 { public: b1 int p1; b2 Error!! int p2; Base class does not include everything in the Derived class. p1 }; However, base class is contained in the Derived class. p2 White w; Blue *b; Pink p; b = &w Uday Khedker 8/23 ACM Summer School on Compilers: Compiling OOP Features Representing Inheritance of Functions • Non-virtual functions are inherited much like data members However, there is a single class-hierachy-wide copy of the code and the address of the object is the first parameter • Virtual functions create interesting possibilities based on the object to which a pointer points to A pointer to a base class object may point to an object of any derived class in the class hierarchy Uday Khedker 9/23 ACM Summer School on Compilers: Compiling OOP Features An Example with Virtual Functions class A { public: virtual void f() {cout << "\tA:f" << endl;} virtual void f(string i) {cout << "\tA:f." << i << endl;} virtual void g() {cout << "\tA:g" << endl;} }; class B : public A { public: virtual void g() {cout << "\tB:g" << endl;} void f() {cout << "\tB:f" << endl;} }; class C : public B { public: void f() {cout<< "\tC:f" << endl;} }; Uday Khedker 10/23 ACM Summer School on Compilers: Compiling OOP Features An Example with Virtual Functions class A { public: virtual void f() {cout << "\tA:f" << endl;} virtual void f(string i) {cout << "\tA:f." << i << endl;} virtual void g() {cout << "\tA:g" << endl;} }; class B : public A { public: virtual void g() {cout << "\tB:g" << endl;} void f() {cout << "\tB:f" << endl;} }; class C : public B { public: void f() {cout<< "\tC:f" << endl;} }; Uday Khedker 10/23 ACM Summer School on Compilers: Compiling OOP Features An Example with Virtual Functions class A { public: virtual void f() {cout << "\tA:f" << endl;} virtual void f(string i) {cout << "\tA:f." << i << endl;} virtual void g() {cout << "\tA:g" << endl;} }; class B : public A { public: virtual void g() {cout << "\tB:g" << endl;} void f() {cout << "\tB:f" << endl;} }; class C : public B { public: void f() {cout<< "\tC:f" << endl;} }; Uday Khedker 10/23 ACM Summer School on Compilers: Compiling OOP Features Examining the Behaviour of Virtual Functions (1) Class Declarations class A { public: virtual void f() virtual void f(string i) virtual void g() }; class B : public A { public: virtual void g() void f() }; class C : public B { public: void f() }; Uday Khedker Calls A a; B b; C c; Output 11/23 ACM Summer School on Compilers: Compiling OOP Features Examining the Behaviour of Virtual Functions (1) Class Declarations class A { public: virtual void f() virtual void f(string i) virtual void g() }; class B : public A { public: virtual void g() void f() }; class C : public B { public: void f() }; Uday Khedker Calls Output A a; B b; C c; p = &a; p->f("classA"); p->f(); p->g(); A:f.classA A:f A:g 11/23 ACM Summer School on Compilers: Compiling OOP Features Examining the Behaviour of Virtual Functions (1) Class Declarations class A { public: virtual void f() virtual void f(string i) virtual void g() }; class B : public A { public: virtual void g() void f() }; class C : public B { public: void f() }; Uday Khedker Calls Output A a; B b; C c; p = &a; p->f("classA"); p->f(); p->g(); p = &b; p->f("classB"); p->f(); p->g(); A:f.classA A:f A:g 11/23 ACM Summer School on Compilers: Compiling OOP Features Examining the Behaviour of Virtual Functions (1) Class Declarations class A { public: virtual void f() virtual void f(string i) virtual void g() }; class B : public A { public: virtual void g() void f() }; class C : public B { public: void f() }; Uday Khedker Calls Output A a; B b; C c; p = &a; p->f("classA"); p->f(); p->g(); p = &b; p->f("classB"); p->f(); p->g(); A:f.classA A:f A:g A:f.classB 11/23 ACM Summer School on Compilers: Compiling OOP Features Examining the Behaviour of Virtual Functions (1) Class Declarations class A { public: virtual void f() virtual void f(string i) virtual void g() }; class B : public A { public: virtual void g() void f() }; class C : public B { public: void f() }; Uday Khedker Calls Output A a; B b; C c; p = &a; p->f("classA"); p->f(); p->g(); p = &b; p->f("classB"); p->f(); p->g(); A:f.classA A:f A:g A:f.classB B:f 11/23 ACM Summer School on Compilers: Compiling OOP Features Examining the Behaviour of Virtual Functions (1) Class Declarations class A { public: virtual void f() virtual void f(string i) virtual void g() }; class B : public A { public: virtual void g() void f() }; class C : public B { public: void f() }; Uday Khedker Calls Output A a; B b; C c; p = &a; p->f("classA"); p->f(); p->g(); A:f.classA A:f A:g p = &b; p->f("classB"); p->f(); p->g(); A:f.classB B:f B:g 11/23 ACM Summer School on Compilers: Compiling OOP Features Examining the Behaviour of Virtual Functions (1) Class Declarations class A { public: virtual void f() virtual void f(string i) virtual void g() }; class B : public A { public: virtual void g() void f() }; class C : public B { public: void f() }; Uday Khedker Calls Output A a; B b; C c; p = &a; p->f("classA"); p->f(); p->g(); A:f.classA A:f A:g p = &b; p->f("classB"); p->f(); p->g(); A:f.classB B:f B:g p = &c; p->f("classC"); p->f(); p->g(); 11/23 ACM Summer School on Compilers: Compiling OOP Features Examining the Behaviour of Virtual Functions (1) Class Declarations class A { public: virtual void f() virtual void f(string i) virtual void g() }; class B : public A { public: virtual void g() void f() }; class C : public B { public: void f() }; Uday Khedker Calls Output A a; B b; C c; p = &a; p->f("classA"); p->f(); p->g(); A:f.classA A:f A:g p = &b; p->f("classB"); p->f(); p->g(); A:f.classB B:f B:g p = &c; p->f("classC"); p->f(); p->g(); A:f.classC 11/23 ACM Summer School on Compilers: Compiling OOP Features Examining the Behaviour of Virtual Functions (1) Class Declarations class A { public: virtual void f() virtual void f(string i) virtual void g() }; class B : public A { public: virtual void g() void f() }; class C : public B { public: void f() }; Uday Khedker Calls Output A a; B b; C c; p = &a; p->f("classA"); p->f(); p->g(); A:f.classA A:f A:g p = &b; p->f("classB"); p->f(); p->g(); A:f.classB B:f B:g p = &c; p->f("classC"); p->f(); p->g(); A:f.classC C:f 11/23 ACM Summer School on Compilers: Compiling OOP Features Examining the Behaviour of Virtual Functions (1) Class Declarations class A { public: virtual void f() virtual void f(string i) virtual void g() }; class B : public A { public: virtual void g() void f() }; class C : public B { public: void f() }; Uday Khedker Calls Output A a; B b; C c; p = &a; p->f("classA"); p->f(); p->g(); A:f.classA A:f A:g p = &b; p->f("classB"); p->f(); p->g(); A:f.classB B:f B:g p = &c; p->f("classC"); p->f(); p->g(); A:f.classC C:f B:g 11/23 ACM Summer School on Compilers: Compiling OOP Features 12/23 Examining the Behaviour of Virtual Functions (2) Class declarations class A { public: virtual void f() virtual void f(string i) virtual void g() }; class B : public A { public: virtual void g() void f() }; class C : public B { public: void f() }; Uday Khedker Output with virtual functions A:f.classA A:f A:g A:f.classB B:f B:g A:f.classC C:f B:g Output with no virtual functions A:f.classA A:f A:g A:f.classB A:f A:g A:f.classC A:f A:g ACM Summer School on Compilers: Compiling OOP Features 13/23 Virtual Function Resolution • Partially static and partially dynamic activity • At compile time, a compiler creates a virtual function table for each class • At run time, a pointer may point to an object of any derived class • Compiler generates code to pick up the appropriate function by indexing into the virtual table to each class (the exact virtual table depends on the pointee object) Uday Khedker ACM Summer School on Compilers: Compiling OOP Features Virtual Function Resolution Requires Dynamic Information A *p; p = ... p->f(); v f() v f(i) v g() v A::f() A f() B *q; v A::f(i) q = ... q->f(); v A::g() v g() v A::f() v B::f() C *r; r = ... r->f(); Uday Khedker B v A::f(i) v A::g() f() C v B::g() 14/23 ACM Summer School on Compilers: Compiling OOP Features Virtual Function Resolution Requires Dynamic Information A *p; p = ... p->f(); v f() v f(i) v g() v A::f() A f() B *q; v A::f(i) q = ... q->f(); In general, at compile time we do C *r; not know the class of the pointee of p r = ... r->f(); v A::g() v g() v A::f() v B::f() Uday Khedker B v A::f(i) v A::g() f() C v B::g() 14/23 ACM Summer School on Compilers: Compiling OOP Features Virtual Function Resolution Requires Dynamic Information A *p; p = ... p->f(); v f() v f(i) v g() v A::f() A f() B *q; v A::f(i) q = ... q->f(); In general, at compile time we do C *r; not know the class of the pointee of p r = ... r->f(); v A::g() v g() v A::f() v B::f() Uday Khedker B v A::f(i) v A::g() f() C v B::g() 14/23 ACM Summer School on Compilers: Compiling OOP Features Virtual Function Resolution Requires Dynamic Information A *p; p = ... p->f(); v f() v f(i) v g() v A::f() A f() B *q; v A::f(i) q = ... q->f(); In general, at compile time we do C *r; not know the class of the pointee of p r = ... r->f(); v A::g() v g() v A::f() v B::f() Uday Khedker B v A::f(i) v A::g() f() C v B::g() 14/23 ACM Summer School on Compilers: Compiling OOP Features Virtual Function Resolution Requires Dynamic Information A *p; p = ... p->f(); v f() v f(i) v g() v A::f() A f() B *q; v A::f(i) q = ... q->f(); v A::g() v g() v A::f() v B::f() C *r; r = ... r->f(); Uday Khedker B v A::f(i) v A::g() f() C v B::g() 14/23 ACM Summer School on Compilers: Compiling OOP Features Virtual Function Resolution Requires Dynamic Information v f() v f(i) v g() A *p; p = ... p->f(); × B *q; q = ... q->f(); C *r; r = ... r->f(); Uday Khedker v A::f() A f() v A::f(i) Compiler can v A::g() g() rule this out vstatically by looking up the declaration of q v A::f() v B::f() f() B v A::f(i) C v A::g() v B::g() 14/23 ACM Summer School on Compilers: Compiling OOP Features Virtual Function Resolution Requires Dynamic Information A *p; p = ... p->f(); v f() v f(i) v g() v A::f() A f() B *q; v A::f(i) q = ... q->f(); v A::g() v g() v A::f() v B::f() C *r; r = ... r->f(); Uday Khedker B v A::f(i) v A::g() f() C v B::g() 14/23 ACM Summer School on Compilers: Compiling OOP Features Virtual Function Resolution Requires Dynamic Information A *p; p = ... p->f(); v f() v f(i) v g() v A::f() A f() B *q; v A::f(i) q = ... q->f(); v A::g() v g() v A::f() v B::f() C *r; r = ... r->f(); Uday Khedker B v A::f(i) v A::g() f() C v B::g() 14/23 ACM Summer School on Compilers: Compiling OOP Features Virtual Function Resolution Requires Dynamic Information A *p; p = ... p->f(); v f() v f(i) v g() v A::f() A f() B *q; v A::f(i) q = ... q->f(); v A::g() v g() v A::f() v B::f() C *r; r = ... r->f(); Uday Khedker B v A::f(i) v A::g() f() C v B::g() 14/23 ACM Summer School on Compilers: Compiling OOP Features Virtual Function Resolution Requires Dynamic Information v f() v f(i) v g() A *p; p = ... p->f(); v A::f() B *q; q = ... q->f(); C *r; r = ... r->f(); Uday Khedker × A f() v A::f(i) v A::g() B v g() Compiler can rulev this out v B::f() A::f() statically v A::f(i) v A::g() v B::g() f() C 14/23 ACM Summer School on Compilers: Compiling OOP Features Virtual Function Resolution Requires Dynamic Information A *p; p = ... p->f(); v f() v f(i) v g() v A::f() A f() B *q; v A::f(i) q = ... q->f(); v A::g() v g() v A::f() v B::f() C *r; r = ... r->f(); Uday Khedker B v A::f(i) v A::g() f() C v B::g() 14/23 ACM Summer School on Compilers: Compiling OOP Features Virtual Function Resolution Requires Dynamic Information v f() v f(i) v g() A *p; p = ... p->f(); v A::f() B *q; q = ... q->f(); C *r; r = ... r->f(); Uday Khedker × × A f() v A::f(i) v A::g() B v g() Compiler can rule out these toov B::f() v A::f() statically v A::f(i) v A::g() v B::g() f() C 14/23 ACM Summer School on Compilers: Compiling OOP Features Virtual Function Resolution Requires Dynamic Information A *p; p = ... p->f(); v f() v f(i) v g() v A::f() A f() B *q; v A::f(i) q = ... q->f(); v A::g() v g() v A::f() v B::f() C *r; r = ... r->f(); Uday Khedker B v A::f(i) v A::g() f() C v B::g() 14/23 ACM Summer School on Compilers: Compiling OOP Features 15/23 Non-Virtual Functions Do Not Require Dynamic Information Non-virtual function = a function which is not virtual in any class in a hierarchy A *p; p = ... p->f(); v f() v f(i) v g() v A::f() A f() B *q; q = ... q->f(); v A::f(i) v A::g() v g() C *r; r = ... r->f(); v A::f() v B::f() v A::f(i) v A::g() Uday Khedker B f() C v B::g() ACM Summer School on Compilers: Compiling OOP Features 15/23 Non-Virtual Functions Do Not Require Dynamic Information Non-virtual function = a function which is not virtual in any class in a hierarchy A *p; p = ... p->f(); v f() v f(i) v g() v A::f() B *q; q = ... q->f(); In general, at compile time we do C *r; know the class of r not = ... the pointee of p r->f(); f() v A::f(i) B v A::g() v g() v A::f() v B::f() v A::f(i) v A::g() Uday Khedker A f() C v B::g() ACM Summer School on Compilers: Compiling OOP Features 15/23 Non-Virtual Functions Do Not Require Dynamic Information Non-virtual function = a function which is not virtual in any class in a hierarchy A *p; p = ... p->f(); v f() v f(i) v g() v A::f() A f() B *q; q = ... q->f(); v A::f(i) v A::g() v g() C *r; r = ... r->f(); v A::f() v B::f() v A::f(i) v A::g() Uday Khedker B f() C v B::g() ACM Summer School on Compilers: Compiling OOP Features 15/23 Non-Virtual Functions Do Not Require Dynamic Information Non-virtual function = a function which is not virtual in any class in a hierarchy A *p; p = ... p->f(); v f() v f(i) v g() × B *q; q = ... q->f(); Even if the pointee is an object class B, p->f() must Cof *r; rbe=A::f() ... because p is a pointer to r->f(); class A Uday Khedker v A::f() A f() v A::f(i) B v A::g() v g() v A::f() v B::f() v A::f(i) v A::g() f() C v B::g() ACM Summer School on Compilers: Compiling OOP Features 15/23 Non-Virtual Functions Do Not Require Dynamic Information Non-virtual function = a function which is not virtual in any class in a hierarchy A *p; p = ... p->f(); v f() v f(i) v g() v A::f() B *q; q = ... q->f(); Even if the pointee is an object class B, p->f() must Cof *r; rbe=A::f() ... because p is a pointer to r->f(); class A Uday Khedker A f() v A::f(i) B v A::g() v g() v A::f() v B::f() v A::f(i) v A::g() f() C v B::g() ACM Summer School on Compilers: Compiling OOP Features 15/23 Non-Virtual Functions Do Not Require Dynamic Information Non-virtual function = a function which is not virtual in any class in a hierarchy A *p; p = ... p->f(); v f() v f(i) v g() v A::f() A f() B *q; q = ... q->f(); v A::f(i) v A::g() v g() C *r; r = ... r->f(); v A::f() v B::f() v A::f(i) v A::g() Uday Khedker B f() C v B::g() ACM Summer School on Compilers: Compiling OOP Features 15/23 Non-Virtual Functions Do Not Require Dynamic Information Non-virtual function = a function which is not virtual in any class in a hierarchy v f() v f(i) v g() A *p; p = ... p->f(); v A::f() B *q; q = ... q->f(); f() v A::f(i) × q is a C *r; pointer to an r = ... object of r->f(); class B B v A::g() v g() v A::f() v B::f() v A::f(i) v A::g() Uday Khedker A f() C v B::g() ACM Summer School on Compilers: Compiling OOP Features 16/23 A Summary of Function Call Resolution • Resolution of virtual functions depends on the class of the pointee object ⇒ Needs dynamic information • Resolution of non-virtual functions depends on the class of the pointer ⇒ Compile time information is sufficient • In either case, a pointee cannot belong to a “higher” class in the hierarchy (“higher” class = a class from which the class of the pointer is derived) Uday Khedker ACM Summer School on Compilers: Compiling OOP Features Constructing Virtual Function Table (1) class A { public: virtual void f() virtual void f(string i) virtual void g() }; class B : public A { public: virtual void g() void f() }; class C : public B { public: void f() }; Uday Khedker 17/23 ACM Summer School on Compilers: Compiling OOP Features Constructing Virtual Function Table (1) class A { public: virtual void f() virtual void f(string i) virtual void g() }; class B : public A { public: virtual void g() void f() }; class C : public B { public: void f() }; Uday Khedker • Consider a pointer to an object of class A • This pointer could point to an object of class A, B, or C 17/23 ACM Summer School on Compilers: Compiling OOP Features Constructing Virtual Function Table (1) class A { public: virtual void f() virtual void f(string i) virtual void g() }; class B : public A { public: virtual void g() void f() }; class C : public B { public: void f() }; Uday Khedker A v f() v f(i) v g() 17/23 ACM Summer School on Compilers: Compiling OOP Features Constructing Virtual Function Table (1) class A { public: virtual void f() virtual void f(string i) virtual void g() }; class B : public A { public: virtual void g() void f() }; class C : public B { public: void f() }; Uday Khedker A v f() v f(i) v g() v A::f() B f() v A::f(i) v A::g() v g() 17/23 ACM Summer School on Compilers: Compiling OOP Features Constructing Virtual Function Table (1) class A { public: virtual void f() virtual void f(string i) virtual void g() }; class B : public A { public: virtual void g() void f() }; class C : public B { public: void f() }; Uday Khedker A v f() v f(i) v g() v A::f() B C f() v A::f(i) v A::g() v g() v A::f() v B::f() v A::f(i) v A::g() v B::g() f() 17/23 ACM Summer School on Compilers: Compiling OOP Features Constructing Virtual Function Table (2) A::f() A v f() v f(i) v g() A::f(i) A::g() v A::f() f() B::f() B C v A::f(i) v A::g() v g() v A::f() v B::f() v A::f(i) v A::g() Uday Khedker B::g() f() C::f() v B::g() 18/23 ACM Summer School on Compilers: Compiling OOP Features Constructing Virtual Function Table (2) A::f() A v f() v f(i) v g() A::f(i) A::g() v A::f() f() B::f() B C v A::f(i) v A::g() v g() v A::f() v B::f() v A::f(i) v A::g() Uday Khedker B::g() f() C::f() v B::g() 18/23 ACM Summer School on Compilers: Compiling OOP Features Constructing Virtual Function Table (2) A::f() A v f() v f(i) v g() A::f(i) A::g() v A::f() f() B::f() B C v A::f(i) v A::g() v g() v A::f() v B::f() v A::f(i) v A::g() Uday Khedker B::g() f() C::f() v B::g() 18/23 ACM Summer School on Compilers: Compiling OOP Features Constructing Virtual Function Table (2) A::f() A v f() v f(i) v g() A::f(i) A::g() × v A::f() B C f() B::f() v A::f(i) v A::g() v g() v A::f() v B::f() v A::f(i) v A::g() Uday Khedker B::g() f() C::f() v B::g() A::f() is overridden by B::f() 18/23 ACM Summer School on Compilers: Compiling OOP Features Constructing Virtual Function Table (2) A::f() A v f() v f(i) v g() A::f(i) A::g() × v A::f() B C f() B::f() v A::f(i) v A::g() v g() v A::f() v B::f() v A::f(i) v A::g() Uday Khedker B::g() f() C::f() v B::g() A::f(i) is inherited 18/23 ACM Summer School on Compilers: Compiling OOP Features Constructing Virtual Function Table (2) A::f() A v f() v f(i) v g() A::f(i) A::g() × v A::f() B C f() B::f() v A::f(i) v A::g() v g() v A::f() v B::f() v A::f(i) v A::g() Uday Khedker B::g() f() C::f() v B::g() 18/23 ACM Summer School on Compilers: Compiling OOP Features Constructing Virtual Function Table (2) A::f() A v f() v f(i) v g() A::f(i) A::g() × × v A::f() B C f() B::f() v A::f(i) v A::g() v g() v A::f() v B::f() v A::f(i) v A::g() Uday Khedker B::g() f() C::f() v B::g() A::g() is overridden by B::g() 18/23 ACM Summer School on Compilers: Compiling OOP Features Constructing Virtual Function Table (2) A::f() A v f() v f(i) v g() A::f(i) A::g() × × v A::f() B C f() B::f() v A::f(i) v A::g() v g() v A::f() v B::f() v A::f(i) v A::g() Uday Khedker B::g() f() C::f() v B::g() 18/23 ACM Summer School on Compilers: Compiling OOP Features Constructing Virtual Function Table (2) A::f() A v f() v f(i) v g() A::f(i) A::g() × × ×× v A::f() B C f() B::f() v A::f(i) v A::g() v g() v A::f() v B::f() v A::f(i) v A::g() Uday Khedker B::g() f() C::f() v B::g() Both A::f() and B::f() are overridden by C::f() 18/23 ACM Summer School on Compilers: Compiling OOP Features Constructing Virtual Function Table (2) A::f() A v f() v f(i) v g() A::f(i) A::g() × × ×× v A::f() B C f() B::f() v A::f(i) v A::g() v g() v A::f() v B::f() v A::f(i) v A::g() Uday Khedker B::g() f() C::f() v B::g() A::f(i) is inherited 18/23 ACM Summer School on Compilers: Compiling OOP Features Constructing Virtual Function Table (2) A::f() A v f() v f(i) v g() A::f(i) A::g() × × ×× v A::f() B C f() B::f() v A::f(i) v A::g() v g() v A::f() v B::f() v A::f(i) v A::g() Uday Khedker B::g() f() C::f() v B::g() 18/23 ACM Summer School on Compilers: Compiling OOP Features Constructing Virtual Function Table (2) A::f() A v f() v f(i) v g() A::f(i) A::g() × × ×× × v A::f() B C f() B::f() v A::f(i) v A::g() v g() v A::f() v B::f() v A::f(i) v A::g() Uday Khedker v B::g() B::g() f() C::f() A::g() is overridden by B::g() which is inherited 18/23 ACM Summer School on Compilers: Compiling OOP Features Constructing Virtual Function Table (2) A::f() A v f() v f(i) v g() A::f(i) A::g() f() B B::f() v A::f(i) v g() B::g() f() C v A::f(i) v B::g() Uday Khedker C::f() 18/23 ACM Summer School on Compilers: Compiling OOP Features Using the Constructed Virtual Function Table A::f() A *p; p = ... p->f(); B *q; v f() v f(i) v g() A::f(i) A::g() f() B::f() v A::f(i) q = ... q->f(); C *r; r = ... r->f(); Uday Khedker v g() B::g() f() v A::f(i) v B::g() C::f() 19/23 ACM Summer School on Compilers: Compiling OOP Features Using the Constructed Virtual Function Table A::f() A *p; p = ... p->f(); B *q; v f() v f(i) v g() A::f(i) A::g() f() B::f() v A::f(i) q = ... At runtime, two dereferences q->f(); are sufficient to get the callee function (or one followed C dereference, *r; by addition of an offset decided by therfunction = ... prototype, and then the second dereference) r->f(); Uday Khedker v g() B::g() f() v A::f(i) v B::g() C::f() 19/23 ACM Summer School on Compilers: Compiling OOP Features Using the Constructed Virtual Function Table A::f() A *p; p = ... p->f(); B *q; v f() v f(i) v g() A::f(i) A::g() f() B::f() v A::f(i) q = ... At runtime, two dereferences q->f(); are sufficient to get the callee function (or one followed C dereference, *r; by addition of an offset decided by therfunction = ... prototype, and then the second dereference) r->f(); Uday Khedker v g() B::g() f() v A::f(i) v B::g() C::f() 19/23 ACM Summer School on Compilers: Compiling OOP Features Using the Constructed Virtual Function Table A::f() A *p; p = ... p->f(); B *q; v f() v f(i) v g() A::f(i) A::g() f() B::f() v A::f(i) q = ... At runtime, two dereferences q->f(); are sufficient to get the callee function (or one followed C dereference, *r; by addition of an offset decided by therfunction = ... prototype, and then the second dereference) r->f(); Uday Khedker v g() B::g() f() v A::f(i) v B::g() C::f() 19/23 ACM Summer School on Compilers: Compiling OOP Features Using the Constructed Virtual Function Table A::f() A *p; p = ... p->f(); B *q; v f() v f(i) v g() A::f(i) A::g() f() B::f() v A::f(i) q = ... q->f(); C *r; r = ... r->f(); Uday Khedker v g() B::g() f() v A::f(i) v B::g() C::f() 19/23 ACM Summer School on Compilers: Compiling OOP Features Using the Constructed Virtual Function Table A::f() A *p; p = ... p->f(); B *q; v f() v f(i) v g() A::f(i) A::g() f() B::f() v A::f(i) q = ... q->f(); C *r; r = ... r->f(); Uday Khedker v g() B::g() f() v A::f(i) v B::g() C::f() 19/23 ACM Summer School on Compilers: Compiling OOP Features Using the Constructed Virtual Function Table A::f() A *p; p = ... p->f(); This is possible because the B *q; size of the virtual function table is made same for all q = ... classes in the hierarchy q->f(); (there can be only one function with a given name and permutation of types of C *r; the arguments) r = ... r->f(); Uday Khedker v f() v f(i) v g() A::f(i) A::g() f() B::f() v A::f(i) v g() B::g() f() v A::f(i) v B::g() C::f() 19/23 ACM Summer School on Compilers: Compiling OOP Features 20/23 A Summary of Virtual Function Implementation • Compile time activity ◮ ◮ ◮ Uday Khedker Collect all virtual functions across a class hierarchy Ignore non-virtual functions Analyse the class hierarchy to locate the appropriate function with a given permutation of argument types ACM Summer School on Compilers: Compiling OOP Features 20/23 A Summary of Virtual Function Implementation • Compile time activity ◮ ◮ ◮ Collect all virtual functions across a class hierarchy Ignore non-virtual functions Analyse the class hierarchy to locate the appropriate function with a given permutation of argument types • Execution time activity ◮ ◮ ◮ Uday Khedker Dereference object pointer to access the virtual function table Add offset to the base of the table to access the function pointer Dereference the function pointer to make the call ACM Summer School on Compilers: Compiling OOP Features Optimizing Virtual Function Calls Source Code Translated Code A a; B b; C c; A a; B b; C c; p = &a; p->f("AA"); p->f(); p->g(); p = &a; (*((p-> vptr)[1]))(&a, "AA"); (*((p-> vptr)[0]))(&a); (*((p-> vptr)[2]))(&a); p = &b; p->f("BB"); p->f(); p->g(); p = &b; (*((p-> vptr)[1]))(&b,"BB"); (*((p-> vptr)[0]))(&b); (*((p-> vptr)[2]))(&b); p = &c; p->f("CC"); p->f(); p->g(); p = &c; (*((p-> vptr)[1]))(&c,"CC"); (*((p-> vptr)[0]))(&c); (*((p-> vptr)[2]))(&c); Uday Khedker Optimized Code 21/23 ACM Summer School on Compilers: Compiling OOP Features Optimizing Virtual Function Calls Source Code A a; B b; C c; Translated Code Optimized Code A a; B b; C c; p = &a; p = &a; "AA"); p->f("AA"); • Each (*((p-> functionvptr)[1]))(&a, call involves a pointer indirection vptr)[0]))(&a); (*((p-> p->f(); and an array indirection (*((p-> vptr)[2]))(&a); p->g(); Runtime overheads • No pfunction = &b; call can be resolved at link time p = &b; p->f("BB"); Call(*((p-> graph is vptr)[1]))(&b,"BB"); not known and hence (*((p-> vptr)[0]))(&b); p->f(); interprocedural optimizations are prohibited (*((p-> vptr)[2]))(&b); p->g(); p = &c; p->f("CC"); p->f(); p->g(); Uday Khedker p = &c; (*((p-> vptr)[1]))(&c,"CC"); (*((p-> vptr)[0]))(&c); (*((p-> vptr)[2]))(&c); 21/23 ACM Summer School on Compilers: Compiling OOP Features Optimizing Virtual Function Calls Source Code Translated Code Optimized Code A a; B b; C c; A a; B b; C c; A a; B b; C c; p = &a; p->f("AA"); p->f(); p->g(); p = &a; (*((p-> vptr)[1]))(&a, "AA"); (*((p-> vptr)[0]))(&a); (*((p-> vptr)[2]))(&a); p = &a; A::f(&a, "AA"); A::f(&a); A::g(&a); p = &b; p->f("BB"); p->f(); p->g(); p = &b; (*((p-> vptr)[1]))(&b,"BB"); (*((p-> vptr)[0]))(&b); (*((p-> vptr)[2]))(&b); p = &b; A::f(&b,"BB"); B::f(&b); B::g(&b); p = &c; p->f("CC"); p->f(); p->g(); p = &c; (*((p-> vptr)[1]))(&c,"CC"); (*((p-> vptr)[0]))(&c); (*((p-> vptr)[2]))(&c); p = &c; A::f(&b,"CC"); C::f(&c); B::g(&c); Uday Khedker 21/23 ACM Summer School on Compilers: Compiling OOP Features Translating Function Template template <typename T> T myMax(T x, T y) { return (x > y)? x: y; } Uday Khedker int main() { cout << myMax<int>(3, 7); cout << myMax<double>(3.0, 7.0); cout << myMax<char>(’g’, ’e’); } 22/23 ACM Summer School on Compilers: Compiling OOP Features Translating Function Template template <typename T> T myMax(T x, T y) { return (x > y)? x: y; } int main() { cout << myMax<int>(3, 7); cout << myMax<double>(3.0, 7.0); cout << myMax<char>(’g’, ’e’); } T myMax(T, T) [with T = int] ( int x, int y) {. . .} T myMax(T, T) [with T = double] ( double x, double y) {. . .} T myMax(T, T) [with T = char] ( char x, char y) {. . .} int main () { D.22263 = myMax<int> (3, 7); D.22265 = myMax<double> (3.0e+0, 7.0e+0); D.22267 = myMax<char> (103, 101); } Uday Khedker 22/23 ACM Summer School on Compilers: Compiling OOP Features Translating Function Template template <typename T> T myMax(T x, T y) { return (x > y)? x: y; } int main() { cout << myMax<int>(3, 7); cout << myMax<double>(3.0, 7.0); cout << myMax<char>(’g’, ’e’); } T myMax(T, T) [with T = int] ( int x, int y) {. . .} T myMax(T, T) [with T = double] ( double x, double y) {. . .} T myMax(T, T) [with T = char] ( char x, char y) {. . .} int main () { D.22263 = myMax<int> (3, 7); D.22265 = myMax<double> (3.0e+0, 7.0e+0); D.22267 = myMax<char> (103, 101); } Uday Khedker 22/23 ACM Summer School on Compilers: Compiling OOP Features Translating Function Template template <typename T> T myMax(T x, T y) { return (x > y)? x: y; } int main() { cout << myMax<int>(3, 7); cout << myMax<double>(3.0, 7.0); cout << myMax<char>(’g’, ’e’); } T myMax(T, T) [with T = int] ( int x, int y) {. . .} T myMax(T, T) [with T = double] ( double x, double y) {. . .} T myMax(T, T) [with T = char] ( char x, char y) {. . .} int main () { D.22263 = myMax<int> (3, 7); D.22265 = myMax<double> (3.0e+0, 7.0e+0); D.22267 = myMax<char> (103, 101); } Uday Khedker 22/23 ACM Summer School on Compilers: Compiling OOP Features 23/23 Translating Class Template template <typename T> class Array { private: T *ptr; int size; public: Array(T arr[], int s); void print(); }; template <typename T> Array<T>::Array(T arr[], int s) { ptr = new T[s]; size = s; for(int i = 0; i < size; i++) ptr[i] = arr[i]; } template <typename T> void Array<T>::print() { int main() { for (int i = 0; i < size; i++) int arr[5] = {1, 2, 3, 4, 5}; cout<<" "<<*(ptr + i); Array<int> a1(arr, 5); cout<<endl; a1.print(); } } Uday Khedker ACM Summer School on Compilers: Compiling OOP Features 23/23 Translating Class Template template <typename T> class Array { private: T *ptr; int size; public: Array(T arr[], int s); void print(); }; template <typename T> Array<T>::Array(T arr[], int s) { ptr = new T[s]; size = s; for(int i = 0; i < size; i++) ptr[i] = arr[i]; } template <typename T> void Array<T>::print() { int main() { for (int i = 0; i < size; i++) int arr[5] = {1, 2, 3, 4, 5}; cout<<" "<<*(ptr + i); Array<int> a1(arr, 5); cout<<endl; a1.print(); } } Array<T>::Array(T*, int) [with T = int] (struct Array * const this, int * arr, int s) {. . .} void Array<T>::print() [with T = int] (struct Array * const this) {. . .} Uday Khedker ACM Summer School on Compilers: Compiling OOP Features 23/23 Translating Class Template template <typename T> class Array { private: T *ptr; int size; public: Array(T arr[], int s); void print(); }; template <typename T> Array<T>::Array(T arr[], int s) { ptr = new T[s]; size = s; for(int i = 0; i < size; i++) ptr[i] = arr[i]; } template <typename T> void Array<T>::print() { int main() { for (int i = 0; i < size; i++) int arr[5] = {1, 2, 3, 4, 5}; cout<<" "<<*(ptr + i); Array<int> a1(arr, 5); cout<<endl; a1.print(); } } Array<T>::Array(T*, int) [with T = int] (struct Array * const this, int * arr, int s) {. . .} void Array<T>::print() [with T = int] (struct Array * const this) {. . .} Uday Khedker ACM Summer School on Compilers: Compiling OOP Features 23/23 Translating Class Template template <typename T> class Array { private: T *ptr; int size; public: Array(T arr[], int s); void print(); }; template <typename T> Array<T>::Array(T arr[], int s) { ptr = new T[s]; size = s; for(int i = 0; i < size; i++) ptr[i] = arr[i]; } template <typename T> void Array<T>::print() { int main() { for (int i = 0; i < size; i++) int arr[5] = {1, 2, 3, 4, 5}; cout<<" "<<*(ptr + i); Array<int> a1(arr, 5); cout<<endl; a1.print(); } } Array<T>::Array(T*, int) [with T = int] (struct Array * const this, int * arr, int s) {. . .} void Array<T>::print() [with T = int] (struct Array * const this) {. . .} Uday Khedker