#include <stdio.h>
#include <stdlib.h>

// A = f,g + a,b
// B = g + c,d
// C = f,g + p,q

typedef void (*FuncType) (void *) ;

struct DT {
 FuncType F[2];
 int D[2];
};

struct A {
 struct DT dt;
 int a;
 int b;
};

struct B {
 struct DT dt;
 int c;
 int d;
};

struct C {
 struct DT dtAC;
 int a;
 int b;
 struct DT dtB;
 int c;
 int d;
 int p;
 int q;
};

void A_f(void *this) {
 printf("A_f can use a=%d and b=%d\n", *(int *) (this+sizeof (struct DT)),
				  *(int*)(this+sizeof (struct DT)+sizeof (int)));
}
void A_g(void *this) {
 printf("A_g can use a=%d and b=%d\n", *(int *)(this+sizeof (struct DT)),
				  *(int *)(this+sizeof (struct DT)+sizeof (int)));
}
void B_g(void *this) {
printf("B_g can use c=%d and d=%d\n", *(int *)(this+sizeof (struct DT)),
				  *(int *)(this+sizeof (struct DT)+sizeof (int)));
}
void C_f(void *this) {
 printf("C_f can use p=%d and q=%d\n", *(int *)(this+2*sizeof (struct DT)+4*sizeof(int)),
				  *(int *)(this+2*sizeof (struct DT)+5*sizeof (int)));
}
void C_g(void *this) {
 printf("C_g can use p=%d and q=%d\n", *(int *)(this+2*sizeof (struct DT)+4*sizeof(int)),
				  *(int *)(this+2*sizeof (struct DT)+5*sizeof (int)));
}

int main () {

void *a;
void *b;
void *c;

struct DT adt, bdt, cdt, bcdt;

 adt.F[0]=A_f;
 adt.F[1]=A_g;
 bdt.F[0]=B_g;
 cdt.F[0]=C_f;
 cdt.F[1]=C_g;
 bcdt.F[0]=C_g;
 
 adt.D[0]=0;
 adt.D[1]=0;
 bdt.D[0]=0;
 cdt.D[0]=0;
 cdt.D[1]=0;
 bcdt.D[0]=-1*(sizeof(struct A));

 // a = new A, b = new B, c= new C

 a=(void *)malloc(sizeof(struct A));
 b=(void *)malloc(sizeof(struct B));
 c=(void *)malloc(sizeof(struct C));

 ((struct A*) (a))->dt=adt;
 ((struct B*) (b))->dt=bdt;
 ((struct C*) (c))->dtAC=cdt;
 ((struct C*) (c))->dtB= bcdt ;
 
 *((int*)(a+sizeof(struct DT)))=1;
 *((int*)(a+sizeof(struct DT)+sizeof(int)))=2;

 *((int*)(b+sizeof(struct DT)))=3;
 *((int*)(b+sizeof(struct DT)+sizeof(int)))=4;

 *((int*)(c+sizeof(struct DT)))=7;
 *((int*)(c+sizeof(struct DT)+sizeof(int)))=8;
 *((int*)(c+2*sizeof(struct DT)+2*sizeof(int)))=9;
 *((int*)(c+2*sizeof(struct DT)+3*sizeof(int)))=10;
 *((int*)(c+2*sizeof(struct DT)+4*sizeof(int)))=5;
 *((int*)(c+2*sizeof(struct DT)+5*sizeof(int)))=6;


 // a->f();

 ( (FuncType)((struct A *)a)->dt.F[0]) 
 		(a+((struct A *)a)->dt.D[0]);

 // a->g ();

 ( (FuncType)((struct A *)a)->dt.F[1]) 
 		(a+((struct A *)a)->dt.D[1]);

 // b->g();
 ( (FuncType)((struct B *)b)->dt.F[0]) 
 		(b+((struct B *)b)->dt.D[0]);

 // c->f();
 ( (FuncType)((struct C *)c)->dtAC.F[0]) 
 		(c+((struct C *)c)->dtAC.D[0]);
 // c->g();
 ( (FuncType)((struct C *)c)->dtAC.F[1]) 
 		(c+((struct C *)c)->dtAC.D[1]);

 // a = c;

 a = c;

 // a->f();  
 
 ( (FuncType)((struct A *)a)->dt.F[0]) 
 		(a+((struct A *)a)->dt.D[0]);

 // a->g();
 
 ( (FuncType)((struct A *)a)->dt.F[1]) 
 		(a+((struct A *)a)->dt.D[1]);

 // b = c;

 b = c+sizeof(struct A);

 //  b->g();

 ( (FuncType)((struct B *)b)->dt.F[0]) 
 		(b+((struct B *)b)->dt.D[0]);

}



