C'mon, guys!

Gregory Smith greg at utcsri.UUCP
Wed May 28 01:45:32 AEST 1986


In article <1194 at ncoast.UUCP> allbery at ncoast.UUCP (Brandon Allbery) writes:
>I concede.  But it wasn't pointer-vs.-array that threw me; f[] and *f are
>identical, whereas f[5] and *f are NOT and neither are f[] = {3} and *f.
 ^^^^^^^^^
Wrong. They shouldn't be, anyway.

Let's shed a little reality on this:
	int nul_ary[];
	int *p;
	main(){
		int i;
		i = nul_ary[0];
		i = p[0];
	}
------------------ output: ( vax, trimmed )----
	.data
	.comm	_nul_ary,0	; 0 bytes for nul_ary
	.comm	_p,4		; 4 bytes for the pointer
	.text
....
	movl	_nul_ary,-4(fp)	; get i = word @ _nul_ary
	movl	_p,r0		; get p in r0
	movl	(r0),-4(fp)	; get i = word pointed to by p
----------------------
nul_ary is treated as an array that happens to have 0 elements, so
*any* subscript is out of range. It can be seen that `i=nul_ary[0]'
will actually do i=(int)p, since the assembler symbols '_nul_ary' and
'_p' are at the same address. Like I said, out of range.

All four compilers I tried behaved the same way (tho I think 3 are pcc-based).

There are some compilers that represent ( in the symbol table ) an array in
the same way as a pointer. The two are distinguished by setting the array
size to 0 to indicate a pointer. After all, pointers don't have array sizes,
and *nobody* uses 0-sized arrays, right? *wrong*. This is the 'clean' way
of declaring an external array of unspecified size:

extern int array[];	/* or array[0] */

So some compilers will 'accidentally' give you a pointer for a
declaration like this, simply because the dimension in the symbol table is
set to zero, and the resulting entry is the same as that for a pointer.
I.e. The generated code will behave as if you had said `extern int *array;'
Obviously, if the external variable is an array, it ain't gonna woik.

If your compiler produces the same code for both variables in the above
sample prog ( with p and nul_ary ), then it is suffering from this bug.
This should not be construed as a language feature, it is an implementation
botch. Some compilers may get the storage declaration right, and then
get the code generation wrong, so check both.

The only compiler that I know for sure has this botch is C/80 for 8080,
which is not full C anyway. From the way this discussion has been going
there must be others. So if you still think f[] and *f are the same, please
check the generated code. Let me/us know about compilers with this bug.

BTW, if you say f[]={3,4}; the size of the array is set to 2 elements by
counting initializers, so there will be no problem.
-- 
"We demand rigidly defined areas of doubt and uncertainty!" - Vroomfondel
----------------------------------------------------------------------
Greg Smith     University of Toronto      UUCP: ..utzoo!utcsri!greg



More information about the Comp.lang.c mailing list