Path: utzoo!utgpu!watmath!mks!egisin From: egisin@mks.UUCP (Eric Gisin) Newsgroups: comp.lang.c Subject: Re: correct code for pointer subtraction (short reply) Summary: my solution Message-ID: <625@mks.UUCP> Date: 22 Dec 88 00:30:06 GMT References: <597@mks.UUCP> <8377@bloom-beacon.MIT.EDU> <8455@sequent.UUCP> <2245@iscuva.ISCS.COM> Organization: Mortice Kern Systems, Waterloo, Ont. Lines: 38 In article <2245@iscuva.ISCS.COM>, carlp@iscuva.ISCS.COM (Carl Paukstis) writes: > Eric: does this prototype declaration and return type satisfy your needs > to avoid grepping through thousands of lines of code and changing same? It was fairly easy to find relevant code, it was all of the form ... (ptr - array) ... all I had to do was grep for "array". The program was compiled large model, so "array" was implicitly "far*". There was no way I could declare "array" huge, the performance loss would be too great. I had to change the code, and since this is a portable program and I don't like scattering "#if PC" all over the place, I defined a macro PTRDIFF(p,q) and replaced all occurences of (ptr-array) with PTRDIFF(ptr,array). There are several possible definitions for PTRDIFF: #define PTRDIFF(p,q) (int)((TYPE huge*)(p) - (TYPE huge*)(q)) where TYPE has to be replaced with the type of p and q, or #define PTRDIFF(p,q) (int)(((long)(unsigned)(p) - (long)(unsigned)(q)) / sizeof(*q)) Both involve calls to library support functions, but there is a more efficient definition of PTRDIFF that works when p>=q holds (this was the case, I am deriving a non-negative array index from a pointer to an array element). It is: /* machine dependencies */ #if !PC #define PTRDIFF(p, q) ((p) - (q)) #else /* 8086 compiler writers are incapable of generating correct code */ #define PTRDIFF(p, q) (((unsigned)(p) - (unsigned)(q)) / sizeof(*q)) #endif All it does is subtract the pointer offsets, resulting in an *unsigned* (not signed) size_t which I then divide by the object's size.