Path: utzoo!utgpu!water!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!bloom-beacon!bu-cs!polygen!pablo From: pablo@polygen.uucp (Pablo Halpern) Newsgroups: comp.lang.c Subject: Re: volatile, noalias and optimization Message-ID: <145@polygen.UUCP> Date: 29 Apr 88 00:33:37 GMT References: <1547@pt.cs.cmu.edu> Organization: Polygen Corporation, Waltham, MA Lines: 116 > 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 /