tneff@atpal.UUCP (Tom Neff) (04/22/88)
It's been pointed out at some length that the new /volatile/ and /noalias/ keywords are really all about controlling the optimizer in various C implementations, more than about the language itself. Thus /volatile/ says "treat this variable no different syntactically, in type, usage etc., but DON'T optimize access to its memory location when you generate code; go 'to the metal' every blessed time." This is a wonderful feature to have, a real "plus" for systems work... but shouldn't we use #pragma volatile(var1, var2, var3) instead of imposing a new keyword on the language grammar? And ditto for /noalias/, although I had a cow when I saw that keyword suddenly sprinkled through string.h et al. It shouldn't be necessary in the standard library prototypes, for heavens sake. In the cases where it's helpful to let the optimizer know there are no alias paths to a variable, #pragma noalias(var4, var5) ought to be all you need. If XJ311 is worried about the syntax varying from one implementation to the next, they can publish a "guideline" which I'm sure most complying vendors would be happy to follow unless there was a compelling reason to express it differently on some particular machine. -- Tom Neff UUCP: ...uunet!pwcmrd!skipnyc!atpal!tneff "None of your toys CIS: 76556,2536 MCI: TNEFF will function..." GEnie: TOMNEFF BIX: are you kidding?
ljz@fxgrp.fx.com (Lloyd Zusman) (04/23/88)
In article <132@atpal.UUCP> uunet!pwcmrd!skipnyc!atpal!tneff (Tom Neff) writes: >It's been pointed out at some length that the new /volatile/ and /noalias/ >keywords are really all about controlling the optimizer in various C >implementations, more than about the language itself. > ... > ... but shouldn't we use > > #pragma volatile(var1, var2, var3) > > ... And ditto for /noalias/ ... > > #pragma noalias(var4, var5) > > ... Hear hear! This way, those of us who really want one or the other of these constructs could use them all we want, and those others who don't want the namespace cluttered can be happy, too. Of course, we'll probably see a few postings from some C Fundamentalists that try to tell us how we should never write code that needs either of these. I think the term "Fundamentalists" is apt, as these folks aren't satisfied with their own programming holiness, but they feel they have to force the rest of us to program in accordance with their (often misguided) beliefs. Oh well ... that's life on the net. I also presume that the ANSI committee won't follow this excellent suggestion, either (sigh). -- Lloyd Zusman Master Byte Software
karl@haddock.ISC.COM (Karl Heuer) (04/27/88)
In article <132@atpal.UUCP> uunet!pwcmrd!skipnyc!atpal!tneff (Tom Neff) writes: >This is a wonderful feature ... but shouldn't we use > #pragma volatile(var1, var2, var3) >instead of imposing a new keyword on the language grammar? Unless you expand on this a bit, it's not as powerful. I've actually used the declaration "char volatile * volatile p;" (a volatile pointer to volatile memory) -- would your proposal handle this? Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint (In case anyone cares, p was volatile because it was being used by both branches after a fork(), and *p because it was a shared memory segment.)
chasm@killer.UUCP (Charles Marslett) (04/27/88)
In article <132@atpal.UUCP>, tneff@atpal.UUCP (Tom Neff) writes: > It's been pointed out at some length that the new /volatile/ and /noalias/ > keywords are really all about controlling the optimizer in various C > implementations, more than about the language itself. Thus /volatile/ > says "treat this variable no different syntactically, in type, usage etc., > but DON'T optimize access to its memory location when you generate code; > go 'to the metal' every blessed time." This is a wonderful feature to > have, a real "plus" for systems work... but shouldn't we use > > #pragma volatile(var1, var2, var3) > > instead of imposing a new keyword on the language grammar? And ditto for I'll go along with this if we will (for consistency sake) also banish "register", "short" and "void" with it. They all have similar impure usage. "Register" is even an optimizer directive, if I ever saw one. And "void" is documentation/lintification feature that probably doesn't serve its purpose near as well as "volatile" does its own. Sure the language becomes a bit more verbose, somewhat more difficult to read (somewhat more like Pascal (?)), but the inferences are useful when you need them, and I don't like "#pragma" as a compiler directive any more than I did "#line" -- kludges, only if you gotta use 'em! Did I step on any toes this time? > Tom Neff UUCP: ...uunet!pwcmrd!skipnyc!atpal!tneff Charles Marslett chasm@killer.UUCP
edw@IUS1.CS.CMU.EDU (Eddie Wyatt) (04/27/88)
>> It's been pointed out at some length that the new /volatile/ and /noalias/ >> keywords are really all about controlling the optimizer in various C >> implementations, more than about the language itself. >> >> #pragma volatile(var1, var2, var3) >> >> instead of imposing a new keyword on the language grammar? And ditto for > > I'll go along with this if we will (for consistency sake) also banish > "register", "short" and "void" with it. They all have similar impure > usage. "Register" is even an optimizer directive, if I ever saw one. And The criticism of volatile comes mainly from the fact that it's use is more for the optimzer than an aid to the programmer. Register is the only construct you have named above that could directly affect the optimizer. So it is the only construct of relevance that analogies could be drawn from. People have also criticized register for it's role as a optimization hint. > [ranting deleted ] > > Did I step on any toes this time? > Not really, you only show your lack of understanding for the opposing position on volatile. > Charles Marslett > chasm@killer.UUCP I believe that if the non-volatile concept is to be adopted as the default for variables then the volatile declaration should be provided via keyword. The current utilization of the language would dictate the need for such a sematic construct. So it should also be adopted in the syntax. However, if you were to ask me whether I believed non-volatile should be the default, well that's another question. I'm kind of swaying between the the fundalmentist view and realizes what the pragmaitcs are for both sides. -- Eddie Wyatt e-mail: edw@ius1.cs.cmu.edu
tneff@atpal.UUCP (Tom Neff) (04/27/88)
In article <3637@haddock.ISC.COM> karl@haddock.ima.isc.com (Karl Heuer) asks: >In article <132@atpal.UUCP> uunet!pwcmrd!skipnyc!atpal!tneff (Tom Neff) writes: >>This is a wonderful feature ... but shouldn't we use >> #pragma volatile(var1, var2, var3) >>instead of imposing a new keyword on the language grammar? > >Unless you expand on this a bit, it's not as powerful. I've actually used the >declaration "char volatile * volatile p;" (a volatile pointer to volatile >memory) -- would your proposal handle this? You're right, Karl, the #pragma approach wouldn't work for nested volatile references like your example, and I can't think of a graceful way to extend my proposal to deal with it either. I guess, then, that the compelling argument for extending the name space to include volatile is that it needs syntactic access to the declarations themselves. Thanks for pointing this out! (It's amazing how sweet tempered one feels on reading of noalias's demise...) -- Tom Neff UUCP: ...uunet!pwcmrd!skipnyc!atpal!tneff "None of your toys CIS: 76556,2536 MCI: TNEFF will function..." GEnie: TOMNEFF BIX: are you kidding?
shankar@hpclscu.HP.COM (Shankar Unni) (04/29/88)
> ..... (It's amazing how sweet tempered one feels on reading of noalias's > demise...) I'm a little behind on this topic, but is the demise for real, or just wishful thinking? ------ Shankar Unni "The reports of my demise are a little premature" -- Mark Twain
pablo@polygen.uucp (Pablo Halpern) (04/29/88)
> It's been pointed out at some length that the new /volatile/ and /noalias/ > keywords are really all about controlling the optimizer in various C > implementations, more than about the language itself. No, volatile is not all about controlling the optimizer. It's just that code that needs volatile is MORE LIKELY to break when optimized. It might break on some compilers without optimization. In fact, volatile has less to say about optimization than does register. I think a lot of the debate about the necessity of volatile comes from a lack of understanding about how many subtleties there are in defining the semantics of a language. To show why volatile is really necessary, let me first show why the "assume all variables are volatile" argument is a semantic nightmare. Take the following code: 1 main() 2 { 3 int a, b; 4 5 scanf("%d", &a); 6 b = 2*a; 7 printf("%d\n", b); 8 } Assume I run this program and type the number 5 at the keyboard. Would you have any hesitation about claiming that this program would produce "10" as its output? No? So you wouldn't have any problem with the compiler optimizing this as: scanf("%d", &a); printf("%d\n", 2*a); would you? Of course not! But if b is assumed volatile, you cannot assume it has the same value in line 7 as it was assigned in line 6. Even if you were to restrict the optimizer, do you really want the program not to mean what it seems to mean? You see, its not just the optimizer that needs variables to be non-volatile. Its needed by both humans and machines for giving meaning to a program. Thus, making all variables effectively volatile not only makes the program harder to optimize, it acually changes the semantics of the language such that almost nothing can be expressed in it. So, variables should not be volatile by default. "Why not use a #pragma to show the exceptions, instead of adding a keyword." you ask. "After all, the use of shared memory and device registers is non-portable anyway, right?" Wrong. The use of these things can be as portable as writing to a file. The fopen() function from the standard library returns a handle that can be used by portable programs to write to a file. The implementation of fopen() is not portable, but the function call itself its. The vender of your C compiler isolated the non-portable stuff so that you could call your program "portable." Similarly, let's assume a set of functions that have non-portable implementations but whose interfaces are portable and well-defined. The function, shared_malloc() returns a pointer to a named piece of shared memory and the functions begin_mutex() and end_mutex() guarentee mutually exclusive access to that memory. The following code would be impossible without volatile: int volatile *shared; /* pointer to volatile int */ shared = (int *) shared_malloc("foo", 10 * sizeof(int)); while (should_fill()) { begin_mutex(shared); if (shared[0] == 0) fill_array(shared); end_mutex(shared); } /* end while */ This type of code could be scattered throughout a 10,000 line program. The program is portable except for the three functions mentioned. If volatile were not standard, this program could not be written portably at all. "But that's multi-tasking and C is not a multi-tasking language." You'd better get use to the fact that multi-tasking is becoming a bigger and bigger port of a programer's life. Even personal computers are beginning to multi-task and these tasks sometimes need to communicate. Signal and interupt handlers are examples of multi-tasking in an otherwise single-task environment. But unlike the ill-fated noalias, you CAN program in C without understanding or using volatile while giving those of us that write system software a way to write portable code. FLAME ON I'm also sick of people implying that any program that is not strictly conforming is totally non-portable. I write a lot of programs that are portable to a large number of machines but are not portable to ALL machines. I also write a lot of programs that have small, self-contained, sections that handle non-portable things like shared memory allocation, interupt handling, semaphores, etc.. Volatile would allow me to keep these sections small and isolated because the program could "admit" that it might be running in a multi-tasking environment. As it is, I'm already playing it a bit dangerous when it comes to signal handlers. If volatile were a #pragma, then every compiler could choose its own syntax and semantics for it, if it were implemented at all. Even among Unix systems, code that used volatile would not be portable! Then maybe IEEE would have to get into the act and define a superset of ANSI C (called POSIX C?) which specifies a standard syntax for the volatile #pragma. Yuk! FLAME OFF Thankfully, it looks like volatile is here to stay. Thankfully, it looks like noalias has bit the dust! Pablo Halpern | mit-eddie \ Polygen Corp. | princeton \ !polygen!pablo (UUCP) 200 Fifth Ave. | bu-cs / Waltham, MA 02254 | stellar /
marcus@illusion.UUCP (Marcus Hall) (04/30/88)
In article <135@atpal.UUCP> tneff@atpal.UUCP (Tom Neff) writes: >In article <3637@haddock.ISC.COM> karl@haddock.ima.isc.com (Karl Heuer) asks: >>In article <132@atpal.UUCP> uunet!pwcmrd!skipnyc!atpal!tneff (Tom Neff) writes: >>>This is a wonderful feature ... but shouldn't we use >>> #pragma volatile(var1, var2, var3) >>>instead of imposing a new keyword on the language grammar? >> >>Unless you expand on this a bit, it's not as powerful. I've actually used the >>declaration "char volatile * volatile p;" (a volatile pointer to volatile >>memory) -- would your proposal handle this? > >You're right, Karl, the #pragma approach wouldn't work for nested volatile >references like your example, and I can't think of a graceful way to extend >my proposal to deal with it either. Well, actually I would think that this could be expressed thusly: char *p; #pragma volatile(p, *p) The problem with this whole approach, however, is that #pragma is explicitly left undefined in ANSI-C. Any compiler implementer is free to do whatever he/she feels like for #pragma. ANSI-C merely defines #pragma to be a standard escape to non-standard directives. Thus, one compiler may implement this in the method mentioned above, but another may implement it as: #pragma vol p; *p; or any number of different ways. Usage of #pragma is by definition non-portable. It is just there for an escape for local additions that may be important enough to add despite the non-portableness. A concept of volatility is important enough (in my opinion, and in quite a few others) that a standard, portable way of specifying this is desirable. Most programs can just ignore volatile and everything will work just fine. Older compilers can just ignore the keyword and assume everything is volatile just like current compilers. Smarter compilers can take advantage of this to avoid re-loading a register with a variable that was already there, avoid doing extra writes to memory, etc. Noalias does enable many optimizations, but while most variables are normally not volatile, most variables ARE noalias. Variables that should be declared volatile are easy to identify; globals that are actually memory mapped i/o registers, variables that are accessed by signal catchers or interrupt routines, etc. Maybe it would make more sense to define a keyword "aliased" which would be tagged onto variables that actually ARE referenced by multiple means and let the compiler treat variables as noalias unless it has its address taken or it is declared "aliased". Of course, globals would need to be declared "aliased" if its address were taken *anywhere*. Anyhow, it seems that noalias should be implemented by some compiler somewhere through a technique similar to what you have proposed before it gets worked into the standard. If it really works and there aren't subtle disasters that arise from its implementation, THEN incorporate it into ANSI-C-rev2. Marcus Hall ..!{ihnp4,mcdchg}!illusion!marcus
ray@micomvax.UUCP (Ray Dunn) (05/04/88)
In article <145@polygen.UUCP> pablo@polygen.uucp (Pablo Halpern) writes: >> It's been pointed out at some length that the new /volatile/ and /noalias/ >> keywords are really all about controlling the optimizer in various C >> implementations, more than about the language itself. > >No, volatile is not all about controlling the optimizer. It's just that >code that needs volatile is MORE LIKELY to break when optimized. It might >break on some compilers without optimization. In fact, volatile has >less to say about optimization than does register. > >I think a lot of the debate about the necessity of volatile comes from >a lack of understanding about how many subtleties there are in defining >the semantics of a language. > Unfortunately, the above statements are off the mark. Volatile is *indeed* only required to control the optimization, *from the compilers' point of view*. "Volatile" and "register" etc are not part of the subtleties of the semantics of the *language*, but are defining something about the *environment* in which the compiled code is to be run. The examples cited only showed the compiler being told to avoid non-volatile dependant optimizations because of environmental requirements. Programs run in *real machines*. I agree fully that the concept of volatility may imply a great deal, including the examples cited by Pablo, but only if the definition of the *environment* in which the program is running also makes these implications valid. >1 main() >2 { >3 int a, b; >4 >5 scanf("%d", &a); >6 b = 2*a; >7 printf("%d\n", b); >8 } > If b in the above is defined as volatile, the *compiler* must assume it can change between line 6 and 7, and (only) control its optimization, but the *programmer* needs to read some other spec to determine its true nature! Indeed, declaring b volatile may not be adequate, because it may change after it has been loaded into some register deep in the heart of the printf function. In that case the *programmer* has to take very special care with b. Special care that a compiler might never be expected to provide. No one has suggested (have they?) that the ANSI 'C' volatile keyword fully covers the requirements of these special architectural features, only that the compiler can at least be forced to produce something *predictable* in the cases where special features are being manipulated. Remember, the "volatile" we are discussing, is the keyword as defined in the ANSI 'C' definition, not that defined in the OED. >FLAME ON > I'm also sick of people implying that any program that is not > strictly conforming is totally non-portable. I write a lot of > programs that are portable to a large number of machines but > are not portable to ALL machines. I also write a lot of programs > that have small, self-contained, sections that handle non-portable > things like shared memory allocation, interupt handling, semaphores, > etc.. These people are the Fundamentalists. Only they believe that being non-portable is in itself Not A Good Thing Under Any 'C'ircumstances. > If volatile were a #pragma, then every compiler could choose its > own syntax and semantics for it, if it were implemented at all. > Even among Unix systems, code that used volatile would not be > portable! Now that we have the current ANSI standard (nearly) put to bed, perhaps we can feel free to discuss what should be included in the *next* revision without worrying about being told "it's too late" (:-). Frankly, I think that instead of "volatile" what is *really* needed is a *contextural* "dont optimize"/"optimize" set of switch pairs to handle such things as volatility and, god forbid, alias assumption relaxation. I wouldn't dare to suggest the syntax at this stage, but I *don't* think a #pragma is the correct vehicle, as this need to be a basic language feature, not a compiler specific option. Remember in these days of microprocessors, a compiler for a particular CPU can make *no* assumptions about the architecture that the compiled code is running on, other than the instruction set. Writing a compiler for a 68000 is a different exercise than writing one for a VAX, which is a fully defined environment. So it's not reasonable to make these controls a compiler specific thing. They *have* to be part of the language. -- Ray Dunn. | UUCP: ..!{philabs, mnetor}!micomvax!ray Philips Electronics Ltd. | TEL : (514) 744-8200 Ext: 2347 600 Dr Frederik Philips Blvd | FAX : (514) 744-6455 St Laurent. Quebec. H4M 2S9 | TLX : 05-824090