3.1.10 Making the compiler happy

If we are to generate compilable C code, we need to make sure all pointer type checking are valid. The can be done by making the this pointer of all the virtual methods void *. In other words, in our example, replace

void X_m1(struct X *this);

with

void X_m1(void *this);

This also means that every this-> in the original code should be replaced by ((struct X *)this)-> in the subroutine. To reduce typing, we can also do the following:

void X_m1(void * _this)  
{  
  struct X *this = (struct X *)_this;  
  // now we can just refer to ‘‘this’’ with the proper type  
}

Once we remove the type information of the the virtual methods, then we can edit the vtables accordingly. The vtables starting on line 10 can be replaced by the vtables in listing 5.


Listing 5:voidptr
 
1struct X_vtable 
2{ 
3  int id; 
4  void (*m1)(void *this); 
5  int offset_m1; 
6  void (*m2)(void *this); 
7  int offset_m2; 
8} _X_vtable = { X_id, X_m1, 0, X_m2, 0 }
9 
10struct YX_vtable 
11{ 
12  int id; 
13  void (*m1)(void *this); 
14  int offset_m1; 
15  void (*m2)(void *this); 
16  int offset_m2; 
17  void (*m3)(void *this); 
18  int offset_m3; 
19} _YX_vtable = { Y_id, X_m1, 8, Y_m2, 0, Y_m3, 0 };

This change, in return, makes it possible to perform the indirect call on line 66 (in listing 4 because the pointer has no type information.