Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!ucbvax!decwrl!purdue!haven!adm!smoke!gwyn From: gwyn@smoke.BRL.MIL (Doug Gwyn ) Newsgroups: comp.std.c Subject: Re: Testing Equal Pointers Message-ID: <9945@smoke.BRL.MIL> Date: 29 Mar 89 16:49:03 GMT References: <1989Mar21.085704.15894@ateng.ateng.com> <16039@cup.portal.com> <375@sdti.SDTI.COM> <9930@smoke.BRL.MIL> <377@sdti.SDTI.COM> Reply-To: gwyn@brl.arpa (Doug Gwyn (VLD/VMB) ) Organization: Ballistic Research Lab (BRL), APG, MD. Lines: 62 In article <377@sdti.SDTI.COM> turner@sdti.UUCP (0006-Prescott K. Turner, Jr.) writes: >... doesn't the standard permit odd behavior in a case like the following: > char a[LIMIT]; > char b[LIMIT]; > ... > if (a+LIMIT == b) ... >It appears that a+LIMIT may compare equal to b, in which case 3.3.9 Actually, 3.3.8. >says they point to the same object (b[0]) or one past the last element of the same array object (a). These are indistinguishable possibilities in this example, but that's not considered to pose a practical problem. >But doesn't the standard permit the behavior which happens with large >model compilers for MS-DOS, in which they point to the same object and >compare not equal? I guess you're implying that the MS-DOS behavior >is covered by saying that a+LIMIT does not point to an object. `a+LIMIT' is not guaranteed to point to an object, although it might do so "accidentally" as in this example. There are a number of ways I might construct a pointer to a valid object, many of them quite implementation-dependent. The pANS requires that all "valid" (i.e. portable) pointer operations that are guaranteed by the standard to produce pointers to the same object (or one past the last element of an array), will produce pointers that compare equal. The important point is that valid pointer operations that could produce equal pointers (depending on run-time variables) but happen to have produced unequal pointers are definitely guaranteed not to refer to the same object, so that for example simple comparison of links in a circular list can be used to determine when the list has been traversed. If MS-DOS implementations can, through valid pointer operations, produce pointers to the same object that might compare unequal, then the standard requires some form of "normalization" be performed before the comparison, in order to assure that the pointers do compare equal. This property is considered essential for reliable C programming. >Erroneous code is definitely a concern. It is impractical for the standard to attempt to constrain the behavior of code that does not obey the constraints of the standard. Think about it. If a pointer has been produced via valid operations, it may be tested against the addresses of each element of an array object to tell whether or not the pointer "lies within" the array. Comparison with just the first and last (plus one?) elements of the array is not sufficient, because "normalization" is not required in such a case. As I recall, the committee didn't think < or > between different array object pointers was of sufficient practical importance to require the extra normalization operations. Frankly, I have to wonder how anyone could let their code get so far out of hand as to not know what their pointers are pointing to. The only practical application for this question I've been able to think of is to determine whether it is possible to implement memmove() in portable ANSI C. If segmented implementations normalize pointers when they are passed as function arguments, there should be no problem, otherwise memmove() requires an implementation-dependent solution.