Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!att!cbnewsl!dfp From: dfp@cbnewsl.ATT.COM (david.f.prosser) Newsgroups: comp.std.c Subject: Re: Out-of-bounds pointers Message-ID: <2222@cbnewsl.ATT.COM> Date: 11 Oct 89 19:22:41 GMT References: <976@crdos1.crd.ge.COM> Reply-To: dfp@cbnewsl.ATT.COM (david.f.prosser) Organization: AT&T Bell Laboratories Lines: 53 In article <976@crdos1.crd.ge.COM> davidsen@crdos1.UUCP (bill davidsen) writes: > Consider: a program is going to read some LARGE number of values in >the range 30000-30006. It wants to count the number of occurences of >each value. Therefore: > long ShortVect[10] = {0,0,0,0,0,0,0,0,0,0}, *Ptr, Val; > > Ptr = &ShortVect[-30000]; > while ((Val = MyRead()) > 0) Ptr[Val]++; > > Note that by creating the pointer to an invalid address we now can add >the value as a subscript. The address modified is *always* valid (if the >input is in range), the vector doesn't need to be 30007 in length, and >you don't have to subtract 30000 each time. This relies on the "recovery" of the pointer value through pointer arithmetic on the invalid value. On architectures in which overflow and underflow on pointers produce quiet wrap-around, you are correct that this sort of approach will work. > I make no claim that this is the only way to do this, simple that >there are programs around which actually do use this trick (I saw it in >a net program). I submit that this is neither sloppy programming or >meaningless, and that it is "not illegal" by K&R 1st Ed. It's a trick to >save some space and CPU, something anyone on a small machine tries to do. >| I have no idea what you mean by "prevailing practice". > Prevailing practice means what it says, that before compilers were >modified to make it illegal such code would work on most machines, such >as Sun, Vax, PC, Cray, PDP-11, etc. I think that fairly represents at >least 80% of the machines and users running pre-ANSI C. I claim that most (all?) of these can be caused to produce some sort of "noise" on overflow and/or underflow, most likely raising a computational exception signal. While, by default, some (all?) silently wrap, there has been no guarantee that this behavior must occur. As such, the prevailing practice does not guarantee that this approach will behave as desired. The X3J11 committee tried its best to mean it when it gave guarantees. It is entirely due to this sort of issue that asynchronous signal handling is so restrictive. This doesn't mean that you shouldn't write code like the above, just that you write it knowing what is required for an architecture to guarantee this not-strictly-portable approach. There are portability trade-offs made in virtually all C programs, unfortunately many are simply not recognized as such by the programmer. Dave Prosser ...not an official X3J11 answer...