Pointer/array compatibility

Tom Karzes karzes at mfci.UUCP
Tue Oct 3 16:55:07 AEST 1989


In article <19880 at mimsy.UUCP> chris at mimsy.UUCP (Chris Torek) writes:
-Concerning the bogus acceptance of
-
-	int **ipp;
-	ipp = <expression of type pointer-to-array-5-of-int>;
-
-The Ultrix VAX `cc' compilers (all of them) are derived from buggy
-4.2BSD VAX compilers.  One would think that, 4.3BSD-tahoe having been
-out for several years, including its considerably less buggy VAX PCC,
-DEC might have at least imported some of the more major fixes.

This isn't entirely accurate.  The original C compilers, including the
original pcc, all accepted this.  Basically, it wouldn't complain about
such assignments provided the number of *'s and []'s matched.  This clearly
doesn't make much sense in any cases involving more than one level of this,
but I know that Dennis Ritchie once claimed that it was legal C.  Perhaps
it was regarded as a sloppy shortcut (I'm not trying to justify it, because
I've always hated it).  Perhaps he actually regarded it as a bug which had
lapsed into a feature.

Here's an excerpt from some mail that Bjarne sent me several years ago
when we were discussing this issue:

>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!

My original complaint was that C didn't allow the address-of operator to
be applied to arrays.  In the case of array "a" above, I calimed that "&a"
should be equivalent to "(int (*)[5][7]) a", and in my original example
I used this cast in the assignment to "p".  Apparently Dennis claimed that
you could get away with using "(int ***) a", in spite of the fact that
the types are incompatible and could never be used interchangeably.

My impression is that this has been "fixed" from time to time in various
pcc-derived compilers.  I don't know what the latest AT&T and BSD pcc
compilers do.  My personal preference is to "fix" it and give an error
in cases like this.  I can imagine 3 cases when this might arise:

    1.  It was a genuine bug which needed to be fixed.

    2.  The user knew what he/she wanted, but didn't know to express it
        in C, and eventually discovered that using this cast made the
        compiler shut up and accept the assignment.  In this case the
        user simply didn't know C and could very well be misled by the
        fact that the compiler accepts it, even if it happens to do what
        was intended.

    3.  The user knows how to do it the right way, but knows that the
        compiler will accepts this and is just being lazy.  In this case
        he/she should probably have just used the correct cast in the first
        place.



More information about the Comp.lang.c mailing list