Help me cast this!: Ultrix 2.x bug

Wayne A. Throop throopw at xyzzy.UUCP
Sat May 14 05:12:08 AEST 1988


> guy at gorodish.Sun.COM (Guy Harris)
>> PS Dennis claims that this is C:
>> main()
>> {
>> 	int a[5][7] ;
>> 	int (*p)[5][7];
>>
>> 	p = (int***) a; /* no & */
>> 	printf("a %d p %d *p %d\n",a,p,*p); /* a == p == *p !!!  */
>> 	(*p)[2][4] = 123 ;
>>	printf("%d\n",a[2][4]); /* 123 */
>> }
>> It works!  Amazing!
> The "(int ***)" cast is incorrect; "p" does
> *NOT* have type "pointer to pointer to pointer to 'int'."

Guy, of course, is correct.  But I'd like to elaborate on this central
point, and explain it slightly differently than does Guy.

On a system where pointers all have the same format regardless of type,
the assignment of p would work as outlined above if it were rendered in
ANY of these ways:

        p = (int *)a;
        p = (int **)a;
        p = (int ****)a;
        p = (char *)a;
        p = (void *)a;
        p = a;

On many systems it would even work as

        p = (int)a;
        p = (long)a;

and so on and on, because everything that follows the assignment depends
upon the type of p AND NOT on the type of the expression assigned to p.

In particular, think of what would happen if you were to replace the "p"
in the assignment 

        (*p)[2][4] = 123;

with the supposedly identical ((int ***)a).  That is, what would you
expect to happen in this program:


main(){
    int a[5][7] ;
    (*((int ***)a))[2][4] = 123 ;
    printf("%d\n",a[2][4]);
}

Careful study of this altered example should convince you that (int ***)
is not anything NEAR the same type as (int (*)[5][7]).

--
You will not see a monster {at Loch Ness}
just as millions before you have not.
                        --- Charls Kuralt
-- 
Wayne Throop      <the-known-world>!mcnc!rti!xyzzy!throopw



More information about the Comp.lang.c mailing list