Xref: utzoo comp.sys.ibm.pc:22918 comp.sys.intel:648 Path: utzoo!attcan!uunet!lll-winken!ames!elroy!gryphon!greg From: greg@gryphon.COM (Greg Laskin) Newsgroups: comp.sys.ibm.pc,comp.sys.intel Subject: Re: correct code for pointer subtraction Keywords: C pointer math has machine dependent limitations Message-ID: <10444@gryphon.COM> Date: 8 Jan 89 02:08:02 GMT References: <597@mks.UUCP> <3845@pt.cs.cmu.edu> <18123@santra.UUCP> <6604@killer.DALLAS.TX.US> <9878@drutx.ATT.COM> Reply-To: greg@gryphon.COM (Greg Laskin) Organization: Trailing Edge Technology, Redondo Beach, CA Lines: 82 In article <9878@drutx.ATT.COM> mayer@drutx.ATT.COM (gary mayer) writes: >In article <18123@santra.UUCP>, tarvaine@tukki.jyu.fi (Tapani Tarvainen) writes: > >> The same error occurs in the following program >> (with Turbo C 2.0 as well as MSC 5.0): >> >> main() >> { >> static int a[30000]; >> printf("%d\n",&a[30000]-a); >> } >> >> output: -2768 > >I grant that this is probably not the answer you would like, but it >is the answer you should expect once pointer arithmetic is understood. > >First, pointers are addresses. good > >Second, when doing pointer arithmetic a scaling factor is used. In pointer >subtraction, the result is the number of objects (integers here) between >the two pointers. good >Third, you might expect the answer to be 30,000, the result of 60,000 / 2. >This doesn't happen because of the 16 bit size, the fact that the result >of pointer subtraction is specified to be an integer, and a "weak" but consider: unsigned a = 0, b = 60000; int size=2; main() { printf("%d\n", (a-b)/size; } That is what the compiler is supposed to be doing. Go ahead, try it on your 16 bit compiler ... you'll get 30,000. Pointers are not ints. Pointers have no signs. The compiler in question has pointers typed incorrectly. That the result is an int has nothing at all to do with the internal math involved in the calculation. (Observant readers will point out that the result can not correctly express a number of array elements > 32767 on a 16 bit machines which is a problem with pointer subtraction involving character arrays). >The problem is complicated on the 8088, etc. machines further because >a "far" pointer allows for arrays larger than the 16 bit integer size >can express. The result of the subtraction of far pointers should be >a long integer, but I do not know what those compilers do. Subtraction of two far pointers which point to the same data aggregate are guaranteed to yield a result <65535. Only the lower 16 bits of the pointers are subtracted. If the two pointers are not pointing to the same aggregate, the result will be wrong (actually undefined). You probably mean "hugh" pointers. Hugh pointers and far pointers don't exist in the C language. The far and hugh extensions to the language gurantee defined results only under narrowly defined conditions. > >In summary, be careful with pointers on these machines, and try to >learn about how things work "underneath". The C language is very >close to the machine, and there are many times that this can have >an effect - understanding and avoiding these where possible is what >writing portable code is all about. good -- Greg Laskin greg@gryphon.COM !gryphon!greg gryphon!greg@elroy.jpl.nasa.gov