[comp.lang.c] Volatile is Necessary

crowl@cs.rochester.edu (Lawrence Crowl) (03/28/88)

The `volatile' type qualifier of ANSI C has recently been criticized as a
frill.  While this assertion is arguable for uniprocessors, it is not true for
shared-memory multiprocessors.  Processes on such machines communicate via
updates to a shared variables.  These updates may occur at arbitrary times
relative to one of the observing processes.  If there is no mechanism to
indicate when a variable referenced by one process may be modified by another
process, the compiler must assume that all variables may be modified at any
time.  In other words, the compiler must assume that all variables are
`volatile'.  This limits the optimizing effectiveness of compilers
substantially.  This limitation is severe because most variables are not
shared.  The compiler is forced to use sub-optimial code for 99% of its
references in order to obtain correctness on the other 1%.  Shared-memory
multiprocessors need the `volatile' concept in order to use highly optimizing
compilers.  The `volatile' concept could be provided as a pragma, but the
concept must exist.  
-- 
  Lawrence Crowl		716-275-9499	University of Rochester
		      crowl@cs.rochester.edu	Computer Science Department
...!{allegra,decvax,rutgers}!rochester!crowl	Rochester, New York,  14627

gwyn@brl-smoke.ARPA (Doug Gwyn ) (03/28/88)

In article <8107@sol.ARPA> crowl@cs.rochester.edu (Lawrence Crowl) writes:
>shared-memory multiprocessors.  Processes on such machines communicate via
>updates to a shared variables.

You need a hell of a lot more than "volatile" to properly
synchronize concurrent processes.

tneff@atpal.UUCP (Tom Neff) (03/28/88)

In article <7569@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>You need a hell of a lot more than "volatile" to properly
>synchronize concurrent processes.

You do, but not from the language itself!  Just about everything else you
need for multiprocessing, you can write yourself as external support routines.
Interrupt handlers and volatile variables are all the language has to give
you.  Fortunately most implementations have some sort of interrupt extension,
but even where there isn't one you can write an assembly-language front end
to call your "C" handler cleanly.  It's not that simple with the shared
variables (or memory mapped I/O, which is just as prevalent) - you really
need some help from the compiler to do things efficiently.  TMN

-- 

Tom Neff 

walter@garth.UUCP (Walter Bays) (03/29/88)

In article <8107@sol.ARPA> crowl@cs.rochester.edu (Lawrence Crowl) writes:
>The `volatile' type qualifier of ANSI C has recently been criticized as a
>frill.  While this assertion is arguable for uniprocessors, it is not true for
>shared-memory multiprocessors.  [...] If there is no mechanism to
>indicate when a variable referenced by one process may be modified by
>another process, the compiler must assume that all variables may be
>modified at any time.  [...] This limits the optimizing effectiveness
>of compilers substantially. [...]

The 'volatile' keyword would also work for uniprocessor device
drivers.  How about setjmp()?  Or side effects of functions with
"dangerous" pointers?
-- 
------------------------------------------------------------------------------
Any similarities between my opinions and those of the
person who signs my paychecks is purely coincidental.
E-Mail route: ...!pyramid!garth!walter
USPS: Intergraph APD, 2400 Geng Road, Palo Alto, California 94303
Phone: (415) 852-2384
------------------------------------------------------------------------------

jas@llama.rtech.UUCP (Jim Shankland) (03/29/88)

In article <7569@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
> [About "volatile" being necessary for concurrent processes using
> shared memory:]
>You need a hell of a lot more than "volatile" to properly
>synchronize concurrent processes.

True enough, but not relevant.  Assuming you *have* the "hell of a lot
more" -- System V semaphores, for example -- you still need "volatilie."
Therefore, "volatile" is hardly an esoteric frill.
Jim Shankland
  ..!ihnp4!cpsc6a!\
               sun!rtech!jas
 ..!ucbvax!mtxinu!/

  > The preceding message was brought to you courtesy of Eddie       <
  > Enterprises, a broadly diversified, multinational corporation    <
  > bringing software, roofing supplies, exquisite keyboard sounds,  <
  > and other fine products to a hungry world.                       <

pf@diab.UUCP (Per Fogelstr|m) (03/29/88)

In article <7569@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>In article <8107@sol.ARPA> crowl@cs.rochester.edu (Lawrence Crowl) writes:
>>shared-memory multiprocessors.  Processes on such machines communicate via
>>updates to a shared variables.
>
>You need a hell of a lot more than "volatile" to properly
>synchronize concurrent processes.

I don't beleive that "volatile" was intended to be a mechanisim for
processor synchronization, rather a way to indicate that a "memory"
location has side effects, for example when it's read. For those of
You that don't normally do system and driver programming it's qite
meaningless, but boy how nice it is to be able to use the -O switch
when compiling a driver wich requires fast interrupt turnaround.

nevin1@ihlpf.ATT.COM (00704a-Liber) (03/30/88)

In article <580@garth.UUCP> walter@garth.UUCP (Walter Bays) writes:
>The 'volatile' keyword would also work for uniprocessor device
>drivers.  How about setjmp()?  Or side effects of functions with
>"dangerous" pointers?

setjmp() is a function call (in much the same way as fork(), exec(),
exit(), etc.) and is not part of the language specification itself (it is
not in section 3 of the draft standard).  Same is true about side effects of
functions of dangerous pointers.  'Volatile', however, IS part of the
language specification.  I consider it to be a 'frill' because nothing else
in the language specification addresses hardware, per se.
-- 
 _ __			NEVIN J. LIBER	..!ihnp4!ihlpf!nevin1	(312) 510-6194
' )  )				"The secret compartment of my ring I fill
 /  / _ , __o  ____		 with an Underdog super-energy pill."
/  (_</_\/ <__/ / <_	These are solely MY opinions, not AT&T's, blah blah blah

gillies@uiucdcsp.cs.uiuc.edu (03/30/88)

C is not a multiprocessor systems programming language.  I'm sorry for
you multiprocessor programmers.  My advice to you is to buy
hypercubes, write in assembly language, or develop your own language.

We don't yet understand how to program multiprocessors well, or even
if shared-memory multiprocessing is the wave of the future.  Please
don't jump the gun by extending the C language too soon.  When
multiprocessing is solved, C will probably have been dead for many
years, and a multiprocessing language (perhaps a distant descendant)
will perform its function.

You can get what you want by adding a compiler-specific (#pragma type)
extension, with no loss of generality.  Do you think "volatile" will
make your programs portable to other multiprocessors????  Dream on!
Your arguments about shared-memory multiprocessors just are not
convincing.

THE ONLY reason to keep it in the language is if you can argue it's
important for uniprocessing.  I believe it might be important for
someone implementing monitors (a la MESA), if monitor locks could span
blocks, not just entire procedures.  But in this case, it's probably a
better idea to implement concurrency control directly in the language,
since this type of extension has been extensively researched.


I believe that you sincerely need this feature, but I also sincerely
believe that most people won't need it.  In top-quality standards
work, you learn to leave out the nonessentials.  Others can put them
in at their own discretion.

Don Gillies {ihnp4!uiucdcs!gillies} U of Illinois
            {gillies@p.cs.uiuc.edu}

wes@obie.UUCP (Barnacle Wes) (03/31/88)

In article <8107@sol.ARPA>, crowl@cs.rochester.edu (Lawrence Crowl) writes:
> The `volatile' type qualifier of ANSI C has recently been criticized as a
> frill.  While this assertion is arguable for uniprocessors, it is not true for
> shared-memory multiprocessors.  Processes on such machines communicate via
> updates to a shared variables.  These updates may occur at arbitrary times
> relative to one of the observing processes.  If there is no mechanism to
> indicate when a variable referenced by one process may be modified by another
> process, the compiler must assume that all variables may be modified at any
> time.

The `volatile' qualifier is also a must for such things as I/O
processors that do not produce interrupts.  Typically with such a
device, you will poll the status register at a predetermined interval,
and when the operation is complete, you can go on to the next
operation on that device.

These types of devices are used quite a bit in imbedded systems where
the speed of the device is not critical, and the interrupt(s) are
already heavily used for speed-critical devices/operations.  You
certainly don't want the compiler to optimize away your check on the
status register!

-- 
    /\              -  "Against Stupidity,  -    {backbones}!
   /\/\  .    /\    -  The Gods Themselves  -  utah-cs!utah-gr!
  /    \/ \/\/  \   -   Contend in Vain."   -  uplherc!sp7040!
 / U i n T e c h \  -       Schiller        -     obie!wes

jgm@K.GP.CS.CMU.EDU (John Myers) (03/31/88)

Is R. Stallman's reading of the ANSI draft wrong, or isn't it
necessary to declare automatic variables as 'volatile' in order to
guarantee that their values will be preseved across a setjmp/longjmp?
(as otherwise they could be placed in registers)

If RMS is right, then the committee botched setjmp/longjmp.

-- 
_.John G. Myers		Internet: John.Myers@cs.cmu.edu
			LoseNet:  ...!seismo!hao!wiscvm.wisc.edu!k!nobody

eric@pyrps5 (Eric Bergan) (03/31/88)

In article <1259@PT.CS.CMU.EDU>, jgm@K.GP.CS.CMU.EDU (John Myers) writes:
> 
> Is R. Stallman's reading of the ANSI draft wrong, or isn't it
> necessary to declare automatic variables as 'volatile' in order to
> guarantee that their values will be preseved across a setjmp/longjmp?
> (as otherwise they could be placed in registers)
> 
> If RMS is right, then the committee botched setjmp/longjmp.

	I'm jumping into the middle of this argument, so please forgive
me if this has been already stated.

	I think there are more serious problems with setjmp/longjmp
than just the volatile issues of variables. There is also the problem
of common subexpressions kept in temporary registers spanning the
setjmp call. While perhaps far-fetched, it is possible to think of
expressions consisting solely of automatic variables that are provably
non-aliased, so that they would not be invalidated by a procedure
call (such as setjmp), and common subexpressions of these that might
be kept in registers, for use inside the body of the setjmp block.

	Clearly, when longjmp jumps into this, these temporary registers
will probably no longer contain the expected subexpressions, and the
code within the setjmp block will fail.

	My guess is that some kind of declaration of setjmp itself
is necessary, to let the compiler know that nothing can be trusted
across this function call. Either that, or a true exception handling
mechanism for C that doesn't completely invalidate modern optimizers.

darin@laic.UUCP (Darin Johnson) (03/31/88)

In article <378@ma.diab.UUCP>, pf@diab.UUCP (Per Fogelstr|m) writes:
> In article <7569@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
> >You need a hell of a lot more than "volatile" to properly
> >synchronize concurrent processes.
> 
> I don't beleive that "volatile" was intended to be a mechanisim for
> processor synchronization, rather a way to indicate that a "memory"
> location has side effects, for example when it's read. For those of
> You that don't normally do system and driver programming it's qite
> meaningless, but boy how nice it is to be able to use the -O switch
> when compiling a driver wich requires fast interrupt turnaround.

For a real life example...  There are quite a few languages in VMS that
have a 'volatile' keyword as a language extension.  I have actually
needed to use something like this to do the following (synopsis):

  volatile int op_cnt;
  .
  .
  void read_ast(.....) {
    .
    .
    op_cnt += z; 
    .
    .
  }

  .
  .
  sys$qio(.., read_ast, ..); /* sys$qio will call read_ast() asynchronously */
  .
  .
  /* now do some expression involving op_cnt, pass it to a function, 
     take its address(!), etc. */

If the word volatile is removed, I could not get consistent results
when optimization was turned on.  This was because op_cnt can get
changed at anytime, even between an add and a store instruction.
If I explicitly turned off optimization (it is on by default) then
everything would start working fine.  Of course, the above code is
bad programming, but you should get the general idea.

A #pragma could be used instead, but if any sort of similar asynchronous
routines get put into a standard (POSIX or otherwise) then 'volatile' will
have to be used instead of '#pragma' to make the code portable (or
else require '#pragma volatile' to be in every compiler you want to
port to).
-- 
Darin Johnson (...ucbvax!sun!sunncal!leadsv!laic!darin)
              (...lll-lcc.arpa!leadsv!laic!darin)
	All aboard the DOOMED express!

chris@mimsy.UUCP (Chris Torek) (03/31/88)

In article <1259@PT.CS.CMU.EDU> jgm@K.GP.CS.CMU.EDU (John Myers) writes:
>Is R. Stallman's reading of the ANSI draft wrong, or isn't it
>necessary to declare automatic variables as 'volatile' in order to
>guarantee that their values will be preseved across a setjmp/longjmp?

[\S => section symbol; |word| => C-style text)

p. 119, \S 4.6.2.1, The |longjmp| function

    All accessible objects have values as of the time |longjmp| was
 called, except that the values of objects of automatic storage
 duration that do not have |volatile| type and have been changed
 between the |setjmp| invocation and |longjmp| call are indeterminate.

    As it bypasses the usual function call and return mechanisms,
 ...  However, if the |longjmp| function is invoked from a nested
 signal handler (that is, from a function invoked as the result of
 a signal raised during the handling of another signal), the behavior
 is undefined.  [This answers another recent question.]

On p. 118 (\S 4.6.1.1, The |setjmp| macro), however, we see that

    The |setjmp| macro shall be implemented as a macro, not as an
 actual function.  If the macro definition is suppressed in order
 to access an actual function, the behavior is undefined.

No reason is given here for this requirement (which, incidentally,
makes it technically illegal NOT to |#define setjmp| as something, even
if it is just as |_setjmp|), but it would make sense if it were
intended as a constraint on the *programmer* so that |<setjmp.h>| could
say, e.g.,

	#define setjmp(env) _builtin_setjmp(env)

which would allow the compiler to implement this as a builtin, and
thus to `fix' all local automatic variables, so that the constraint
in \S 4.6.2.1 need not apply.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

tneff@atpal.UUCP (Tom Neff) (03/31/88)

In article <77200028@uiucdcsp> gillies@uiucdcsp.cs.uiuc.edu writes:
>C is not a multiprocessor systems programming language.  I'm sorry for
>you multiprocessor programmers.  My advice to you is to buy
>hypercubes, write in assembly language, or develop your own language.

Thank you very much, Don!  You have taken the manly step of writing off
"C" as an operating systems language.  Don't tell the Unix programmers,
though, they might take it to heart.  :-)




-- 

Tom Neff 

walter@garth.UUCP (Walter Bays) (03/31/88)

In article <77200028@uiucdcsp> gillies@uiucdcsp.cs.uiuc.edu writes:
>C is not a multiprocessor systems programming language.  I'm sorry for
>you multiprocessor programmers.  My advice to you is to buy
>hypercubes, write in assembly language, or develop your own language [...]
>You can get what you want by adding a compiler-specific (#pragma type)
>extension, with no loss of generality.  [...]
>THE ONLY reason to keep it in the language is if you can argue it's
>important for uniprocessing.  [...]

I agree that C is a poor language for multiprocessors, though I'd
probably choose Ada over assembler.  I'm not concerned with
multiprocessors.  I am concerned with a C compiler that can generate
highly optimized code for 95% of application programs without fear of
generating incorrect code for systems programs, or for 5% of programs
with dangerous use of pointers and signals.  Yes, a #pragma would work
just fine.  So would a 'cc -Passed_Lint', but it would be nice if the
same mechanism worked on any UNIX machine, and great if it also worked
on non-UNIX machines.  You're right that, for standards, simpler is
better (another reference to Ada :-).  Maybe this is a POSIX issue
rather than a C issue.
-- 
------------------------------------------------------------------------------
Any similarities between my opinions and those of the
person who signs my paychecks is purely coincidental.
E-Mail route: ...!pyramid!garth!walter
USPS: Intergraph APD, 2400 Geng Road, Palo Alto, California 94303
Phone: (415) 852-2384
------------------------------------------------------------------------------

edw@IUS1.CS.CMU.EDU (Eddie Wyatt) (03/31/88)

 >You need a hell of a lot more than "volatile" to properly
 >synchronize concurrent processes.

However, your synchronization primatives may use shared mem that requires
the volatile semantics.  One example is spin locks.


-- 

Eddie Wyatt 				e-mail: edw@ius1.cs.cmu.edu

daw@houxs.UUCP (David Wolverton) (03/31/88)

In article <77200028@uiucdcsp>, gillies@uiucdcsp.cs.uiuc.edu writes:
[stuff deleted about multiprocessing]
> THE ONLY reason to keep it [volatile] in the language is if you can argue it's
> important for uniprocessing....

[I think this discussion is getting sidetracked.  The question is whether
the volatile type qualifier should have been included in the ANSI C (draft)
standard.]

As an implementor of an optimizer, I rejoiced when I saw that the committee
had added 'volatile' to the language.

The point of volatile is that 98% of a program's variables (and 99% in portable
programs) will *not* be qualified with 'volatile', which allows optimizers
to make assumptions about the optimizations which can be applied to a variable.
Without 'volatile', the optimizer has to use a pessimistic assumption about
the variables so that it won't stomp on the 1-5% of the variables which care
about it!

'volatile' is *not* present to help any specific thing like interrupt handlers,
multiprocessing, shared memory, etc.  Rather, it helps them all, because its
*absence* in "normal" code tells the optimizer that none of those funky things
are happening behind its back.  That is why 'volatile' is in the language.

Dave Wolverton
AT&T

dkc@hotlr.ATT (Dave Cornutt) (04/01/88)

In article <77200028@uiucdcsp> gillies@uiucdcsp.cs.uiuc.edu writes:
 > C is not a multiprocessor systems programming language.  I'm sorry for
 > you multiprocessor programmers.  My advice to you is to buy
 > hypercubes, write in assembly language, or develop your own language.

One of the reasons C exists is to replace assembly language in many
applications.

 > We don't yet understand how to program multiprocessors well, or even
 > if shared-memory multiprocessing is the wave of the future.

Shared memory is not confined to multiprocessors; it's useful on
uniprocessors too.  And it's not something in the far future;
it exists now, in both the SysV and BSD implementations of Unix
(although neither one is really spiffy), and in VMS, Amigados,
OS/2 I think, and probably a bunch more OS'es that I don't know
about.  Although the calls to set up the shared memory spaces on
these systems are not portable, the use of the resulting space
should be, since it's just a memory space.  C will lose out if
it fails to support these uses.

 > You can get what you want by adding a compiler-specific (#pragma type)
 > extension, with no loss of generality.

On the contrary, all generality is lost.  If it is made a pragma, vendors
will not be required to support it, and no specific syntax will be required
of those that do.

 > THE ONLY reason to keep it in the language is if you can argue it's
 > important for uniprocessing.

Here's a list of some of the things that you can't do properly on an
optimizing compiler without it:

signal catching
coroutines
device drivers
any kind of asynchronous event handler

These are common things right now.  What you're suggesting is that these
should not be considered conforming programs, because they use OS features
that are not portable to another OS.  Unfortunately, if you provide no
standardized way to do volatiles, then you not only can't port this code
to a different machine, you probably can't even port it to a different
conforming compiler ON THE SAME MACHINE!  Not only that, but you might
not even be able to port it to a different version of the SAME compiler!

An optimizing compiler without a volatile primitive cannot properly
compile a Unix kernel (or any other).

-- 
Dave Cornutt, AT&T Bell Labs (rm 4A406,x1088), Holmdel, NJ
UUCP:{ihnp4,allegra,cbosgd}!hotly!dkc
"The opinions expressed herein are not necessarily my employer's, not
necessarily mine, and probably not necessary"

henry@utzoo.uucp (Henry Spencer) (04/02/88)

> 	My guess is that some kind of declaration of setjmp itself
> is necessary, to let the compiler know that nothing can be trusted
> across this function call...

If you inspect the X3J11 rules about setjmp carefully, you will see a
set of restrictions aimed at making it easy for compilers to recognize
it as a special case.  Optimizing compilers undoubtedly will.  Non-
optimizing compilers will simply have to be a bit conservative.  This
is not a disaster.

The current rules about automatic variables *are* a bit of a disaster,
but nobody in his right mind will implement them (and some of us are
going to try to get them changed).  The traditional rule, that only
explicitly-register variables are unsafe after longjmp, is adequate:
any compiler that is smart enough to promote things into registers
without being asked is smart enough to notice the setjmp and take
precautions.
-- 
"Noalias must go.  This is           |  Henry Spencer @ U of Toronto Zoology
non-negotiable."  --DMR              | {allegra,ihnp4,decvax,utai}!utzoo!henry

gordon@sneaky.UUCP (04/03/88)

>     The |setjmp| macro shall be implemented as a macro, not as an
>  actual function.  If the macro definition is suppressed in order
>  to access an actual function, the behavior is undefined.
> No reason is given here for this requirement (which, incidentally,
> makes it technically illegal NOT to |#define setjmp| as something, even
> if it is just as |_setjmp|), but it would make sense if it were
> intended as a constraint on the *programmer* so that |<setjmp.h>| could
> say, e.g.,
> 	#define setjmp(env) _builtin_setjmp(env)

I interpret the requirement that setjmp be implemented as a macro as
requiring that you cannot (portably) take the address of setjmp, and
put it in a function pointer.  Therefore, the compiler may assume that 
all calls through function pointers are NOT calls to setjmp.  Further, you 
can make the compiler recognize all calls to setjmp, by doing things
like:

# define setjmp(env) (_builtin_setjmp(env) + 0)

where the +0 ensures that &setjmp draws an error message, and the name
_builtin_setjmp is recognized by the compiler and makes it flush out
common subexpressions, etc.


				Gordon Burditt
				...!ihnp4!sys1!sneaky!gordon

sarima@gryphon.CTS.COM (Stan Friesen) (04/04/88)

In article <4192@ihlpf.ATT.COM> nevin1@ihlpf.UUCP (00704a-Liber,N.J.) writes:
>
>  'Volatile', however, IS part of the
>language specification.  I consider it to be a 'frill' because nothing else
>in the language specification addresses hardware, per se.

	But 'volatile' does NOT address *hardware*, it addresses asynchronous
change is a value, which *may* be due to hardware, or to the execution of a
logically asynchronous control thread(either a seperate process or a control
thread in a single process such as a signal handler). It is needed often enough
that I think it makes a meaningful addition to the language.

peter@sugar.UUCP (Peter da Silva) (04/04/88)

In article <77200028@uiucdcsp>, gillies@uiucdcsp.cs.uiuc.edu writes:
> I believe that you sincerely need this feature, but I also sincerely
> believe that most people won't need it.  In top-quality standards
> work, you learn to leave out the nonessentials.  Others can put them
> in at their own discretion.

You need volatile to efficiently implement device drivers.

Given this, and assuming that you actually do want to write your drivers
in something other than assembly, volatile is necessary.
-- 
-- Peter da Silva  `-_-'  ...!hoptoad!academ!uhnix1!sugar!peter
-- Disclaimer: These U aren't mere opinions... these are *values*.

nevin1@ihlpf.ATT.COM (00704a-Liber) (04/05/88)

In article <3113@gryphon.CTS.COM> sarima@gryphon.CTS.COM (Stan Friesen) writes:
>In article <4192@ihlpf.ATT.COM> nevin1@ihlpf.UUCP (00704a-Liber,N.J.) writes:
>>  'Volatile', however, IS part of the
>>language specification.  I consider it to be a 'frill' because nothing else
>>in the language specification addresses hardware, per se.

>	But 'volatile' does NOT address *hardware*, it addresses asynchronous
>change is a value, which *may* be due to hardware, or to the execution of a
>logically asynchronous control thread(either a seperate process or a control
>thread in a single process such as a signal handler). It is needed often enough
>that I think it makes a meaningful addition to the language.

Ane I quote from section 3.5.3 of the standard:

	"Examples

	An object declared

		extern const volatile int real_time_clock;

	may be modifilable by hardware, but cannot be assigned to,
	incremented, or decremented."
	
	"[footnote] 52.  A volatile declaration may be used to describe an
	object corresponding to a memory-mapped input/output port or an
	object accessed by an asynchronously interrupting function. [...]"
	
Although what you say about asynchronous functions are true, I still
maintain that 'volatile' does indeed address hardware.  I do believe that
there is a need for a 'do_not_optimize' keyword (at least in non-strict
conforming programs); why call it volatile when we really mean
do_not_optimize??
-- 
 _ __			NEVIN J. LIBER	..!ihnp4!ihlpf!nevin1	(312) 510-6194
' )  )				"The secret compartment of my ring I fill
 /  / _ , __o  ____		 with an Underdog super-energy pill."
/  (_</_\/ <__/ / <_	These are solely MY opinions, not AT&T's, blah blah blah

pablo@polygen.uucp (Pablo Halpern) (04/05/88)

In article <1988Mar29.004454.2867@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes:
>... The principal problem with #pragma
>is that it is not portable, since its semantics are not standardized, but
>the sort of code we're talking about isn't portable anyway.

Not true.  Volatile was invented to solve some of the problems associated
with multiprocessing or multitasking.  These problems surface even in
programs that do no interprocess communication if they use the signal()
fuction which exists in the standard library.  A signal handler is very
similar to a separate task that shares memory with the main-line program.
Any variable that might be changed by a signal handler should be declared
volatile since it may change at any time on receipt of a signal.  If
it is not declared volatile, the main-line program may continue to use
an old cached value long after the variable has changed, potentially
going into an endless loop waiting for it to change.  Similar situations
occure with setjmp()/longjmp().

From article <4192@ihlpf.ATT.COM>, by nevin1@ihlpf.ATT.COM (00704a-Liber):
> setjmp() is a function call (in much the same way as fork(), exec(),
> exit(), etc.) and is not part of the language specification itself (it is
> not in section 3 of the draft standard).  Same is true about side effects of
> functions of dangerous pointers.  'Volatile', however, IS part of the
> language specification.  I consider it to be a 'frill' because nothing else
> in the language specification addresses hardware, per se.

This is also true of signal() but without volatile, signal() could not
be written.  I see nothing wrong with having language features that support
the library definition.  After all, the purpose of this whole process is
to design a language that supports the writing of programs.

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.  Ugg!
FLAME OFF

Volatile must stay, noalias must go!

Pablo Halpern		|	mit-eddie \
Polygen Corp.		|	princeton  \ !polygen!pablo  (UUCP)
200 Fifth Ave.		|	bu-cs      /
Waltham, MA 02254	|	stellar   /

karl@haddock.ISC.COM (Karl Heuer) (04/07/88)

In article <-63852956@sneaky> gordon@sneaky.UUCP writes:
># define setjmp(env) (_builtin_setjmp(env) + 0)
>where the +0 ensures that &setjmp draws an error message

It doesn't work that way.  "&setjmp" (more generally, any use of a function-
-like macro without a left parenthesis) will not be recognized as a macro and
hence no substitution will take place.  (This feature allows you to take the
address of putchar, for example, even if it's implemented as a macro.)  So you
might as well use "#define setjmp(env) __builtin_setjmp(env)" and let the
linker complain about the unresolved symbol "setjmp".

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint

chip@ateng.UUCP (Chip Salzenberg) (04/07/88)

In article <4267@ihlpf.ATT.COM> nevin1@ihlpf.UUCP (00704a-Liber,N.J.) writes:
>Although what you say about asynchronous functions are true, I still
>maintain that 'volatile' does indeed address hardware.  I do believe that
>there is a need for a 'do_not_optimize' keyword (at least in non-strict
>conforming programs); why call it volatile when we really mean
>do_not_optimize??

"Prior art."

Besides, I'm sure you use "creat" despite its poorly chosen name.  :-)

--
Chip Salzenberg                 "chip@ateng.UU.NET" or "codas!ateng!chip"
A T Engineering                 My employer's opinions are a trade secret.
       "Anything that works is better than anything that doesn't."

pablo@polygen.uucp (Pablo Halpern) (04/08/88)

Sorry if you got this twice, but I think my original posting got lost ...

In article <1988Mar29.004454.2867@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes:
>... The principal problem with #pragma
>is that it is not portable, since its semantics are not standardized, but
>the sort of code we're talking about isn't portable anyway.

Not true.  Volatile was invented to solve some of the problems associated
with multiprocessing or multitasking.  These problems surface even in
programs that do no interprocess communication if they use the signal()
fuction which exists in the standard library.  A signal handler is very
similar to a separate task that shares memory with the main-line program.
Any variable that might be changed by a signal handler should be declared
volatile since it may change at any time on receipt of a signal.  If
it is not declared volatile, the main-line program may continue to use
an old cached value long after the variable has changed, potentially
going into an endless loop waiting for it to change.  Similar situations
occure with setjmp()/longjmp().

From article <4192@ihlpf.ATT.COM>, by nevin1@ihlpf.ATT.COM (00704a-Liber):
> setjmp() is a function call (in much the same way as fork(), exec(),
> exit(), etc.) and is not part of the language specification itself (it is
> not in section 3 of the draft standard).  Same is true about side effects of
> functions of dangerous pointers.  'Volatile', however, IS part of the
> language specification.  I consider it to be a 'frill' because nothing else
> in the language specification addresses hardware, per se.

This is also true of signal() but without volatile, signal() could not
be written.  I see nothing wrong with having language features that support
the library definition.  After all, the purpose of this whole process is
to design a language that supports the writing of programs.

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.  Ugg!
FLAME OFF

Volatile must stay, noalias must go!

Pablo Halpern		|	mit-eddie \
Polygen Corp.		|	princeton  \ !polygen!pablo  (UUCP)
200 Fifth Ave.		|	bu-cs      /
Waltham, MA 02254	|	stellar   /

meissner@xyzzy.UUCP (Michael Meissner) (04/09/88)

In article <140@polygen.UUCP> pablo@polygen.uucp (Pablo Halpern) writes:
| Not true.  Volatile was invented to solve some of the problems associated
| with multiprocessing or multitasking.  ...

Ughhh, let me throw some facts on this issue.  Volatile was NOT
originally added for shared memory multiprocessing systems.  Around the
ANSI X3J11 meeting in Concord or the meeting before that (around 3-4
years ago), const had been put in from the C++ implementation.  At that
time, it was felt that about half of the C programmers in the world were
writing C for the bare iron, ie OS developers, and device controllers
(which some in the committee calls toasters in a pejoritive sense), and
the other half were writing on UNIX.  It was for the first set of users
that volatile was invented, since we had many people who for example
wanted to do something silly like run highly optimizing compilers on
their operating system or product without breaking it (once they
identified the critical places).  If you look at the current C
programmers, I would suspect the bare iron people are considerably in
the minority, and that MSDOS C programmers have surpased the UNIX C
programmers.
-- 
Michael Meissner, Data General.		Uucp: ...!mcnc!rti!xyzzy!meissner
					Arpa/Csnet:  meissner@dg-rtp.DG.COM

ray@micomvax.UUCP (Ray Dunn) (04/12/88)

In article <77200028@uiucdcsp> gillies@uiucdcsp.cs.uiuc.edu writes:
>
>C is not a multiprocessor systems programming language.  I'm sorry for
>you multiprocessor programmers.  My advice to you is to buy
>hypercubes, write in assembly language, or develop your own language.
>
>We don't yet understand how to program multiprocessors well, or even
>if shared-memory multiprocessing is the wave of the future.  Please
>don't jump the gun by extending the C language too soon....

Unfortunately, "multiprocessor systems" are more common than you might
think.  We are not necessarily talking about esoteric new architectures when
talking multiprocessor.

As an example, there are many PC option cards, especially comms cards, which
are "intelligent", i.e. have a CPU on board.  These often share memory with
the host CPU, and have software in two parts, an option card part, and a
host part, which communicate via this shared memory.

It would be nice to continue to program these devices in 'C'!

Ray Dunn.  ..{philabs, mnetor)!micomvax!ray

mcdonald@uxe.cso.uiuc.edu (04/12/88)

>If you look at the current C
>programmers, I would suspect the bare iron people are considerably in
>the minority, and that MSDOS C programmers have surpased the UNIX C
>programmers.

MS-DOS  ---IS--- "bare iron"! 

jwhitnel@csi.UUCP (Jerry Whitnell) (04/14/88)

In article <225800018@uxe.cso.uiuc.edu> mcdonald@uxe.cso.uiuc.edu writes:
>
>>If you look at the current C
>>programmers, I would suspect the bare iron people are considerably in
>>the minority, and that MSDOS C programmers have surpased the UNIX C
>>programmers.
>
>MS-DOS  ---IS--- "bare iron"! 

I beg to differ.  Bare iron is much better the MS-DOS.  There are no bugs
to get in your way :-).

Jerry Whitnell				Been through Hell?
Communication Solutions, Inc.		What did you bring back for me?
						- A. Brilliant