RE:pointer to pointer to pointer bug in

R. Eastman (eastman@tapestry.llnl.gov)
Tue, 21 Jul 1998 20:37:22 -0700


Masaharu,

Thank you for responding to my question about pointers to pointers to
pointers (e.g. double***). I've taken a look at the cint source
(version 5.13.62), and think I've fixed the problem. By making a
couple of minor modifications to the G__ASSIGN_PVAR(CASTTYPE,CONVFUNC)
and G__GET_PVAR(CASTTYPE,CONVFUNC,CONVTYPE,TYPE,PTYPE) macro
definitions in var.c, it now seems to work great, and able to handle
any number of levels of indirection. I've tested it on
double**** x
and am able to both read and write to
x[i][j][k][m]
(once it has been properly initialized--see pppptest.C below).

There is still a problem with incomplete dereferencing. In the above
example, x[i] is recognized as a double*, instead of a double***, and
although it returns the correct value (address), it thinks x[i][j] is
a double value. Maybe I can figure this out too.

Below are the diffs between my modified var.c and the original 5.13.62
version. After that is a small script (pppptest.C) which I ran to
check that it works.

Cheers
Ron Eastman

+++++++++++++++++++++
diff var.c var.c.orig
+++++++++++++++++++++
135,144c135,136
< /*old code: *((CASTTYPE*)(*(((long*)(*(long *)address))+para[0].obj.i))+para[1].obj.i) */ \
< /* = CONVFUNC(result); */ \
< { /* ron eastman change begins */ \
< int ip; \
< long *phyaddress=(long*)(*(long *)address); \
< for (ip = 0; ip < paran-1; ip++) { \
< phyaddress=(long*)phyaddress[para[ip].obj.i]; \
< } \
< ((CASTTYPE*)(phyaddress))[para[paran-1].obj.i] = CONVFUNC(result); \
< } /* eastman change ends */ \

---
>   *((CASTTYPE*)(*(((long*)(*(long *)address))+para[0].obj.i))+para[1].obj.i) \
> 		= CONVFUNC(result);                                          \
424,430c416
< 	  { /* ron eastman change begins */				      \
< 	    int ip;							      \
< 	    for (ip = 1; ip < paran-1; ip++) {				      \
<           result.ref=(long)((long*)(*(long *)(result.ref))+para[ip].obj.i);   \
< 	    } /* ron eastman change ends */	                              \
< 	  }						                      \
<        result.ref=(long)((CASTTYPE*)(*((long*)(result.ref)))+para[paran-1].obj.i);  \
---
>        result.ref=(long)((CASTTYPE*)(*((long*)(result.ref)))+para[1].obj.i);  \

-------------------------------------- pppptest.C -------------------------------------- { double *x, **xp; double ***xpp, ****xppp; x=(double*)malloc(16*sizeof(double)); xp=(double**)malloc(8*sizeof(double*)); xpp=(double***)malloc(4*sizeof(double**)); xppp=(double****)malloc(2*sizeof(double***));

for (int i = 0; i < 8; i++) { xp[i] = &(x[2*i]); } for (int i = 0; i < 4; i++) { xpp[i] = &(xp[2*i]); } for (int i = 0; i < 2; i++) { xppp[i] = &(xpp[2*i]); } for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { for (int k = 0; k < 2; k++) { for (int m = 0; m < 2; m++) { xppp[i][j][k][m] = i * 1000 + j * 100 + k * 10 + m; printf("xppp[%d][%d][%d][%d] = %f\n", i, j, k, m, xppp[i][j][k][m]); } } } } }