3.1 C equivalent code

The C equivalent code of listing 3 is in listing 4.


Listing 4:Cequivalentcodeoflisting3
 
1enum { X_id, Y_id }
2struct X; // forward declaration of X 
3struct Y; // forward declaration of Y 
4 
5void X_m1(struct X *this); 
6void X_m2(struct X *this); 
7void Y_m2(struct Y *this); 
8void Y_m3(struct Y *this); 
9 
10struct X_vtable  
11{ 
12  int id; 
13  void (*m1)(struct X *this); 
14  int offset_m1; 
15  void (*m2)(struct X *this); 
16  int offset_m2; 
17} _X_vtable = { X_id, X_m1, 0, X_m2, 0 }
18 
19struct YX_vtable 
20{ 
21  int id; 
22  void (*m1)(struct X *this); 
23  int offset_m1; 
24  void (*m2)(struct Y *this); 
25  int offset_m2; 
26  void (*m3)(struct Y *this); 
27  int offset_m3; 
28} _YX_vtable = { Y_id, X_m1, 8, Y_m2, 0, Y_m3, 0 }
29 
30struct X  
31{ 
32  struct X_vtable *pVtable; 
33  int derived_offset; 
34  int n; 
35}
36 
37struct Y  
38{ 
39  struct YX_vtable *pVtableX; 
40  int derived_offset; 
41  struct X superX; 
42  int m; 
43}
44 
45void test(void
46{ 
47  struct X myX; 
48  struct Y myY; 
49  struct X *pX; 
50  struct Y *pY; 
51 
52  // constructor code to initialize points to vtables 
53  myX.pVtable = &_X_vtable;  
54  myX.derived_offset = 0; 
55  myY.pVtableX = &_YX_vtable; 
56  myY.derived_offset = 0; 
57  myY.superX.pVtable = (struct _X_vtable *)&_YX_vtable; // changed on 20061109 
58  myY.superX.derived_offset = 8; 
59  // end constructor code 
60  X_m1(&myX);  
61  X_m1(&myY.superX);  
62  Y_m2(&myY); 
63  pX = &myY.superX; // static up cast  
64  {  
65    struct X_vtable *vtab = pX>pVtable; // changed on 20061109 
66    vtab>m1((((char *)pX)+pX>derived_offset+vtab>offset_m1)); // compiler wont like the pointer type  
67  } 
68  {  
69    struct X_vtable *vtab = pX>pVtable; // changed on 20061109 
70    vtab>m2((((char *)pX)+pX>derived_offset+vtab>offset_m2)); // compiler wont like the pointer type  
71  } 
72  {   
73    // dynamic down cast code 
74    pY = (struct Y *)  
75         (((char *)pX)   
76          sizeof(YX_vtable *));  
77    if (pY>pVtableX>id != Y_id) pY = 0;  
78  } 
79  if (pY) pY>pVtableX>m3(pY);  
80}

There are quite a few interesting things going on here in the C equivalent code for a polymorphic class hierarchy.

  3.1.1 vtable
  3.1.2 The structs
  3.1.3 pVtable initialization
  3.1.4 Regular virtual method invocation
  3.1.5 Inherited virtual method invocation
  3.1.6 Static up cast
  3.1.7 Sticky methods from a superclass pointer
  3.1.8 Dynamic down cast
  3.1.9 Method invocation via pointer
  3.1.10 Making the compiler happy