davidsen@steinmetz.ge.com (William E. Davidsen Jr) (09/08/88)
I recently proofread a manual which stated that even calculating the value of an invalid address could cause a memory fault. I read this to mean that code like: int D_temp[30], /* 30 elements */ *tempr = D_temp-100; /* int tempr[100..129] */ would cause a problem even if the pointer were not dereferenced. I would assume that calculating a value would not EVER cause a dereference (and thereby a fault), no matter how invalid the address. An example in point are the machines which will fault if you try to dereference a NULL pointer. Simply having the value NULL doesn't cause a problem. Is there a portion of dpANS which states that this is/isn't allowed, or that it's implementation dependent? Seems like "common practice" to me, and portable, as long as you don't use the pointer other than as a starting point back to the defined array. BTW: the example above is how you convert a Pascal program with a range to C. Access is rangechecked by a macro package. -- bill davidsen (wedu@ge-crd.arpa) {uunet | philabs}!steinmetz!crdos1!davidsen "Stupidity, like virtue, is its own reward" -me
gwyn@smoke.ARPA (Doug Gwyn ) (09/08/88)
In article <12088@steinmetz.ge.com> davidsen@crdos1.UUCP (bill davidsen) writes: > I recently proofread a manual which stated that even calculating the >value of an invalid address could cause a memory fault. I read this to >mean that ... Yes, that's right. This problem can occur on segemented architectures (the 80*86 is not the only one!) and on tagged (or capability-based) architectures. > An example in point are the machines which will fault if you try to >dereference a NULL pointer. Simply having the value NULL doesn't cause a >problem. Is there a portion of dpANS which states that this is/isn't >allowed, or that it's implementation dependent? A null pointer (which is written as 0 or (some_type *)0, depending on context, also sometimes as NULL for convenience) is part of the C language according to the dpANS. Dereferencing it leads to undefined behavior. Computing a pointer to a nonexistent object (other than just past the end of an array) is also undefined behavior. [This is from memory; certainly the dpANS does not promise that it will work for all conforming implementations.] >Seems like "common practice" to me, Lots of nonportable constructs are commonly encountered. > and portable, ... No, sorry. It happens to work (accidentally) in many cases on many implementations, but since it can fail on some and is not guaranteed, it is not "portable".
apratt@atari.UUCP (Allan Pratt) (09/09/88)
In article <12088@steinmetz.ge.com> davidsen@crdos1.UUCP (bill davidsen) writes: > > I recently proofread a manual which stated that even calculating the > value of an invalid address could cause a memory fault. I suppose that a word-addressing machine could cause a memory fault when you try to put an odd address in an address register: register int *bar = (int *)1; /* address fault */ ============================================ Opinions expressed above do not necessarily -- Allan Pratt, Atari Corp. reflect those of Atari Corp. or anyone else. ...ames!atari!apratt
henry@utzoo.uucp (Henry Spencer) (09/09/88)
In article <12088@steinmetz.ge.com> davidsen@crdos1.UUCP (bill davidsen) writes: > I recently proofread a manual which stated that even calculating the >value of an invalid address could cause a memory fault... This is correct. On single-linear-address-space machines, computing an invalid address just generates a meaningless number. On machines with segments, an address is a structured object: if the address you start with is <segment 456, offset 10> and you try to subtract 20 from it, this may be considered a meaningless and illegal operation -- a kind of underflow -- rather than a legal operation generating meaningless results. It depends on whether the designers were segment purists or not, and on precisely how they defined the format of an address and the semantics of arithmetic on it. >... Is there a portion of dpANS which states that this is/isn't >allowed, or that it's implementation dependent? ... If you study the section on pointer arithmetic, you will find that, with the single exception of a pointer one past the end of an array (not its beginning!), *any* pointer arithmetic which takes you out of the array you started in is allowed to send you off into the twilight zone. Analogies to NULL are invalid; NULL is a special case of a legal pointer which you are not allowed to dereference. -- Intel CPUs are not defective, | Henry Spencer at U of Toronto Zoology they just act that way. | uunet!attcan!utzoo!henry henry@zoo.toronto.edu
daveb@geac.UUCP (David Collier-Brown) (09/12/88)
In article <12088@steinmetz.ge.com> davidsen@crdos1.UUCP (bill davidsen) writes: | I recently proofread a manual which stated that even calculating the | value of an invalid address could cause a memory fault... From article <1988Sep9.164419.12461@utzoo.uucp>, by henry@utzoo.uucp (Henry Spencer): | This is correct. On single-linear-address-space machines, computing an | invalid address just generates a meaningless number. [...] | It depends on whether the designers were segment purists or not, and on | precisely how they defined the format of an address and the semantics | of arithmetic on it. Minor point: if you underflow one one linear-address-space machine, you get the "impossible" (too high) address error. -dave (manufacturer unnamed to protect the guilty) c-b -- David Collier-Brown. | yunexus!lethe!dave 78 Hillcrest Ave,. | He's so smart he's dumb. Willowdale, Ontario. | --Joyce C-B
atbowler@watmath.waterloo.edu (Alan T. Bowler [SDG]) (09/30/88)
In article <12088@steinmetz.ge.com> davidsen@crdos1.UUCP (bill davidsen) writes: > > I recently proofread a manual which stated that even calculating the >value of an invalid address could cause a memory fault. I read this to >mean that code like: > int D_temp[30], /* 30 elements */ > *tempr = D_temp-100; /* int tempr[100..129] */ > >would cause a problem even if the pointer were not dereferenced. I would >assume that calculating a value would not EVER cause a dereference (and >thereby a fault), no matter how invalid the address. > The problem occurs on those smart architectures that validate a pointer when it is loaded into a pointer type register, or the contents of such a register is changed. In your example assume that you coded x = tempr[i]; You really want the compiler to generate lptr PR,tempr Load pointer register PR ldx IX,i Load index register IX ldr AC,[IX,PR] Load data register AC, using PR indexed by IX sldr AC,x Store data register AC into X If the machine does check the register on the load pointer this could well fault. If the compiler is required to accept a sequence like you want then it will be forced to do the address calculation itself with the data registers and manufacture a pointer before it actually tries to do a data fetch. Since data registers on these architectures are often smaller than the pointer registers, this tends to be a painfully slow proceedure. So you can understand the compiler writer deciding to assume that he will only be given programs that are written in the style the machine was designed for and generating the faster sequence. Often the fast method of doing arithmetic on a pointer involves some form of "compute effective address into pointer register". That way the implementor will not continually be complained at, "that the same program written in Pascal runs 'so much faster' than in C". This does not stop you from writing your code sequence. You just must be aware that there are some machines out there that will not run that particular program. Note that nothing in the above says anything about NULL, since it never actually gets used where the compiler must do an address computation.