Path: utzoo!utgpu!water!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!husc6!uwvax!oddjob!mimsy!chris From: chris@mimsy.UUCP (Chris Torek) Newsgroups: comp.lang.c Subject: Re: Volatile is stupid Keywords: Compilers don't know all! Message-ID: <12056@mimsy.UUCP> Date: 21 Jun 88 01:53:41 GMT References: <11837@mimsy.UUCP> <225800035@uxe.cso.uiuc.edu> <5800@aw.sei.cmu.edu> <278@ralph.UUCP> Distribution: na Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 103 >In article <5800@aw.sei.cmu.edu> firth@bd.sei.cmu.edu.UUCP (Robert Firth) >writes: >>... the compiler [could] read a single "target memory definition file", >>or similar, that says >> 00000000..0003ffff is ROM >> 00040000..00ffffff is RAM >> fffffeeb is volatile >>... Not only does this work, it is amenable to decent verification, >>management, configuration control, and maintenance. "Volatile" is >>a hacker's answer. (with which I mostly agree, although I think `hacker's answers' are not inherently wrong.) In article <278@ralph.UUCP> pja@ralph.UUCP (Pete Alleman) writes: >The compiler generally DOES NOT KNOW the address being accessed. And why not? The answer is only that `the compiler' is too limited: >As an example suppose I were to write this routine: >dev_wait (csr) >volatile int *csr; >{ > /* wait for the device to complete some operation */ > while (*csr & DEVBUSY) > /* So this is in the kernel, reasonable example */ > sleep (csr, PRI); >} > >How could the compiler possibly know that the pointer passed >at runtime might point to a volatile location (without the keyword)?? Ask the question this way: Who calls dev_wait? If you look at a PDP-11 kernel, it may look like this: dev_open(dev) dev_t dev; { register struct devdevice *devaddr = DEVADDR; ... dev_wait(&devaddr->dev_csr); ... } So the caller (here dev_open()) *does* know the address being accessed (after a bit of flow analysis). All the compiler need do (`all' he says :-) ) is pass that information on down into the generation of dev_wait(). `But wait!' you object. `What if dev_open is in a separate file?' Compilation (including alias and volatility analysis) need not occur until `link' time. `But wait!' you object. `What if I read the address in at run-time?' main() { int *ip; ... ... read(fd, (char *)&ip, sizeof(ip)); ... while (*ip & BUSY) /* void */; ... } Is *ip volatile? I cannot say---but neither can you. The compiler (which may be disguised as a linker) does not know either. It must therefore assume that it is volatile. The key point here is that there is no algorithmic way to determine volatility in this worst case---so any competent programmer must assume that, if there are any volatile addresses, this code may refer to one. The programmer's only other option is to decree that the program must never read an address that *is* volatile. A programmer who makes such a decree is certain to be surprised by a user. If you meant that *ip had better not be volatile, you should check ip: if (is_volatile(ip)) { fprintf(stderr, "%s: bad input data in %s\n", progname, infile); exit(EX_DATAERR); } while (*ip & BUSY) /* void */; How will you write is_volatile()? On an IBM PC you might say if ((unsigned long)ip >= 640*1024L) ... Once you have done that, the compiler can (by a bit of range checking) also determine that *ip is not volatile. `But wait!' you say. `Even a very fancy optimising ``compiler'' (linker) is going to miss *some* things. Why, we can use some fancy mathematics to prove that it cannot catch everything.' That is so. But how often will this occur in practise? Today, probably all the time; but tomorrow? Five years from now? Fifty? -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris