Xref: utzoo comp.sys.ibm.pc:22657 comp.sys.intel:629 Path: utzoo!utgpu!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!mailrus!ames!killer!chasm From: chasm@killer.DALLAS.TX.US (Charles Marslett) Newsgroups: comp.sys.ibm.pc,comp.sys.intel Subject: Re: correct code for pointer subtraction Summary: Please think about what you say (FLAME) Keywords: C pointer math DAMN WELL IS A BUG!!!! Message-ID: <6604@killer.DALLAS.TX.US> Date: 31 Dec 88 02:25:58 GMT References: <597@mks.UUCP> <3845@pt.cs.cmu.edu> <18123@santra.UUCP> <142@bms-at.UUCP> Organization: The Unix(R) Connection, Dallas, Texas Lines: 57 In article <142@bms-at.UUCP>, stuart@bms-at.UUCP (Stuart Gathman) 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 > > This is entirely correct. The difference of two pointers is an *int*. And unless you have a 15-bit computer, 30000 is a very representable *INT*, so please pay attention to the discussion before asserting something. The compiler is generating a VERY WRONG ANSWER. > If you want an unsigned difference, you need to cast to unsigned > (and/or use %u in the printf). If the difference were defined as > unsigned, how would you indicate negative differences? If you > make the difference long, all the related arithmetic gets promoted > also for a big performance hit. The solution is simple, if you > want an unsigned ptrdiff, cast or assign to unsigned. The result cast to an unsigned is 62768, still not even close to the correct value of 30000. There are two viable solutions: you can write your own assembly language (or C code, even) to calculate the proper result or you can ignore the issue and assume the size of a segment on the Intel architecture is 32K. I have used both solutions. > > This is described in the Turbo C manual. Unfortunately, the Turbo C manual lies (it does not identify all the cases where the compiler gets it wrong -- in fact it looks very much like the Microsoft C compiler documentation, all the same errors, did someone copy? ;^). > Don't flame the 8086 either. The same thing happens in 32-bit machines > (just much less often). 16 bits is 16 bits, and segments are not > the problem. The VAX restricts user programs to 31-bit address space > to avoid this. Actually, in a 32-bit machine the problem is probably more serious if we assume a real 32-bit address, since it may well not support 33+ bit arithmetic even as well as Intel boxes support 17+ bit arithmetic. > -- > Stuart D. Gathman > <..!{vrdxhq|daitc}!bms-at!stuart> Charles Marslett chasm@killer.dallas.tx.us