[comp.unix.xenix] SCO Xenix 'C' pointer bug

wrp@krebs.acc.virginia.edu (Wm Pearson) (08/25/87)

	Attached is a test program which displays a bug I just found
in the SCO 'C' development system 2.1.4 release G.  Compile the
program and run it.  You will find the value of 'dpos' goes up to 3999
just fine, but then becomes negative.  I would appreciate a work-around
that does not require a division by sizeof(struct tstruct). Note
that although the pointers are being treated as ints (intead of unsigned)
in the expression (int)(dptr-diag), they are being treated properly in
the 'dptr<&diag[5000].

============= test.c
Bill Pearson
wrp@virginia.BITNET
...!seismo!virginia!wrp


#include <stdio.h>

struct tstruct {
	int one;
	int two;
	int three;
	int four;
	} *diag, *dptr;

main()
{
	char *calloc();
	unsigned int dpos;
	
	diag = (struct tstruct *)calloc(5000,sizeof(struct tstruct));
	for (dptr=&diag[99]; dptr<&diag[5000]; dptr +=100) {
		dpos = (unsigned int)(dptr-diag);
		printf("%4d %4d\n",dpos,(int)(dptr-diag));
	}
}
=============

news@jpusa1.UUCP (usenet) (08/29/87)

Summary:

Expires:


In article <227@krebs.acc.virginia.edu> wrp@krebs.acc.virginia.edu (Wm Pearson) writes:
-
-	Attached is a test program which displays a bug I just found
-in the SCO 'C' development system 2.1.4 release G.  Compile the
-program and run it.  You will find the value of 'dpos' goes up to 3999
-just fine, but then becomes negative.  I would appreciate a work-around
-that does not require a division by sizeof(struct tstruct). Note
-that although the pointers are being treated as ints (intead of unsigned)
-in the expression (int)(dptr-diag), they are being treated properly in
-the 'dptr<&diag[5000].
-
-============= test.c
-Bill Pearson
-wrp@virginia.BITNET
-...!seismo!virginia!wrp
-
-
-#include <stdio.h>
-
-struct tstruct {
-	int one;
-	int two;
-	int three;
-	int four;
-	} *diag, *dptr;
-
-main()
-{
-	char *calloc();
-	unsigned int dpos;
-	
-	diag = (struct tstruct *)calloc(5000,sizeof(struct tstruct));
-	for (dptr=&diag[99]; dptr<&diag[5000]; dptr +=100) {
-		dpos = (unsigned int)(dptr-diag);
-		printf("%4d %4d\n",dpos,(int)(dptr-diag));
-	}
-}
-=============
The problem seems to be incorect pointer arithmetic and I don't see any
work around.  When the expression '(char *)dptr-(char *)diag' becomes
greater than 0x7fff, there is sign extension(!!!).  This is before the
scaling of sizeof(tstruct).  Use a macro like
#define pos(p,base,type) ((unsigned)((char *)p-(char *)base)/sizeof(type))
and 'dpos = pos(dptr,diag,struct tstruct);'

Stu Heiss {gargoyle,ihnp4}!jpusa1!stu