[comp.std.c] volatile

karl@haddock.ISC.COM (Karl Heuer) (05/17/88)

In article <5367@bloom-beacon.MIT.EDU> peter@athena.mit.edu (Peter J Desnoyers) writes:
>The debate over |volatile| seems to focus on one point: if this keyword is
>only necessary for non-portable code, why does it have to be part of the
>language?  [Goes on to discuss cross-compilers]

There's a simpler refutation: the premise is false.  The signal() function is
part of the standard library, and |volatile| is necessary for handlers of
asynchronous signals.  Earlier I posted a strictly conforming program which
contained some lines like:
  #include <signal.h>
  static volatile sig_atomic_t gotcha = 0;
  static void catch(int signo) { gotcha = 1; }
which argument has not been refuted to my knowledge.

If |volatile| were removed, we'd either have to go back to the old rules
(everything's volatile) or absorb its meaning into |sig_atomic_t|.

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
Followups to comp.std.c.

cquenel@pyramid.pyramid.com (The Prince Who Was A Thousand) (05/17/88)

In article <4025@haddock.ISC.COM> karl@haddock.ima.isc.com (Karl Heuer) writes:
>
>There's a simpler refutation: the premise is false.  The signal() function is
>part of the standard library, and |volatile| is necessary for handlers of
>asynchronous signals.  Earlier I posted a strictly conforming program which
>contained some lines like:
>  #include <signal.h>
>  static volatile sig_atomic_t gotcha = 0;
>  static void catch(int signo) { gotcha = 1; }
>which argument has not been refuted to my knowledge.
>
>If |volatile| were removed, we'd either have to go back to the old rules
>(everything's volatile) or absorb its meaning into |sig_atomic_t|.


To the best of my knowledge, "volatile" is the only way of /guaranteeing/
that a (for instance) local variable will NOT be restored/affected by a
longjmp().  According to the version of the standard I was browsing.

--chris

karl@haddock.ISC.COM (Karl Heuer) (05/18/88)

In article <23502@pyramid.pyramid.com> cquenel@pyramid.UUCP writes:
>In article <4025@haddock.ISC.COM> karl@haddock.ima.isc.com (Karl Heuer) writes:
>>If |volatile| were removed, we'd either have to go back to the old rules
>>(everything's volatile) or absorb its meaning into |sig_atomic_t|.
>
>To the best of my knowledge, "volatile" is the only way of /guaranteeing/
>that a (for instance) local variable will NOT be restored/affected by a
>longjmp().

True.  In addition to absorbing its meaning into |sig_atomic_t|, we'd have to
add a guarantee that setjmp()/longjmp() will properly synchronize *all*
objects (which some of us think should be done anyway).

X3J11 vetoed this because it would setjmp() magic.  I expect that a proposal
to make sig_atomic_t magic would be even worse.

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

barmar@think.COM (Barry Margolin) (09/08/89)

I think that I may have figured out what the earlier poster meant when
he said that the effects of "volatile" aren't observable.

When the volatile modifier is added to a variable, various constraints
are placed on the implementation regarding the compilation of accesses
to that variable.  Conversely, removing the volatile modifier simply
makes some operations implementation-dependent; I don't think it ever
adds any constraints.

Therefore, an implementation that treats all variables as if they were
volatile would be valid.  In such an implementation, adding and
removing volatile modifiers would have no effect on the observable
behavior of the program.

An implementation could also randomly treat non-volatile variables as
if they were volatile.  During testing, the randomness might cause
everything to work as the programmer wants.

The point is that there's no reliable way to test whether the volatile
modifier is ignored by an implementation.  If a pair of programs which
differr only in the use of volatile have the same observable effects,
it could be accidental or it could be because it ignores the modifier.


Barry Margolin
Thinking Machines Corp.

barmar@think.com
{uunet,harvard}!think!barmar

mike@hpfcso.HP.COM (Mike McNelly) (09/13/89)

> In article <1989Sep8.091010.12450@gdt.bath.ac.uk> exspes@gdr.bath.ac.uk (P E Smee) writes:
> >one might ask why you would want to write a chunk
> >of code that has ZERO effect.

> I sometimes do this during program development. I declare the data
> structures and write the code that operates on them, leaving the i/o
> to worry about later. I may want to compile at this point to check
> for errors in the code.

Ah, but any compiler that has optimization capabilities that would allow
it to nullify a useless program invariably does not do such optimization
unless you ask for it with flags such as -O. My guess is that you don't
optimize such a program during development, only after development is
nearly complete.

Mike McNelly
mike%hpfcla@hplabs.hp.com

poser@csli.Stanford.EDU (Bill Poser) (09/14/89)

In article <7330001@hpfcso.HP.COM> mike@hpfcso.HP.COM (Mike McNelly) writes:
>
>Ah, but any compiler that has optimization capabilities that would allow
>it to nullify a useless program invariably does not do such optimization
>unless you ask for it with flags such as -O. My guess is that you don't
>optimize such a program during development, only after development is
>nearly complete.

True, but I often just stick the optimization flag in the Makefile
and don't bother to turn it off during testing. Anyhow, the question I
answered was why one might want to write a "useless" code fragment.
I agree that a compiler that optimizes such a fragment into nothingness
is not a problem if one can disable the optimization.

							Bill

mark@cblpf.ATT.COM (Mark Horton) (09/14/89)

P E Smee writes:
> >one might ask why you would want to write a chunk
> >of code that has ZERO effect.

> I sometimes do this during program development. I declare the data
> structures and write the code that operates on them, leaving the i/o
> to worry about later. I may want to compile at this point to check
> for errors in the code.

If all you want is syntax and semantic checking, you're going to get
that unless the code is surrounded by something like
	#ifdef notdef
	(useless code)
	#endif /* notdef */
which the compiler had better ignore - it might contain comments.
(I hope pANS hasn't outlawed making comments this way and otherwise
neutralizing old code that you might want again someday.)

For the compiler to determine that a particular piece of code is
useless, it has to perform a fair amount of analysis.  It has to
process the preprocessor, syntax, semantics, generate code, and
do some kind of analysis.  A syntax error will certainly be detected
and reported, as will a static semantic error.  Runtime errors are
going to be hard to detect without I/O statements, unless the thing
divides by zero or something without any I/O.  I don't see how any
"useless code deletion" feature is going to get in your way.  It
can't determine that the code is useless without understanding it.

Of course, you could always just use a syntax directed editor.

	Mark

flee@shire.cs.psu.edu (Felix Lee) (09/15/89)

In <7330001@hpfcso.HP.COM>,
   Mike McNelly <mike@hpfcso.HP.COM> writes:
> Ah, but any compiler that has optimization capabilities that would allow
> it to nullify a useless program invariably does not do such optimization
> unless you ask for it with flags such as -O.

Bad assumption.  The High C compiler (on IBM RTs) always does at least
trivial optimization.  Warnings like "Expression has no side effects"
and "Variable is never referenced" mean relevant code has disappeared.
--
Felix Lee	flee@shire.cs.psu.edu	*!psuvax1!flee

haug@cc.Columbia.NCR.COM (10/25/89)

I understand the usage of volatile to indicate that a value may change for
reasons that are not necesarily apparent (hardware registers, interrupts, etc)
and so must be read from memory each time they are referenced.  My question is:
must the value be written each time it is assigned.  The reason I ask is I was
recently playing with a piece of hardware that upon second and subsequent writes
to the register actually went to an alternate register.  Thus for initialization
there were two successive assignments to the same variable.  Many current
compilers would discard the first assignment since its effect is wiped out by
the second.  Does volatile protect this?  If not, is there any method to
accomplish my goal reliably and portably?

Please e-mail response and I will sumarize.

			Share and Enjoy!

			      Brian (haug@Columbia.NCR.COM)

drw@fibonacci.math.mit.edu (Dale R. Worley) (10/26/89)

In article <1989Oct25.020542.13354@cc.Columbia.NCR.COM> haug@cc.Columbia.NCR.COM writes:

   I understand the usage of volatile to indicate that a value may change for
   reasons that are not necesarily apparent (hardware registers, interrupts, etc)
   and so must be read from memory each time they are referenced.  My question is:
   must the value be written each time it is assigned[?]

Yes.  I remember seeing a statement in the draft standard that both
reads and writes to a volatile l-value must be as in the "abstract
machine".

Dale			drw@math.mit.edu

diamond@jit533.swstokyo.dec.com (Norman Diamond) (04/26/91)

In article <1991Apr25.190127.8178@cs.ucla.edu> jon@maui.cs.ucla.edu (Jonathan Gingerich) writes:

>May accessing a volatile cause external (to the program) changes?

Of course; that is the purpose of "volatile."  (Well, half of its purpse :-)

>If so, then it could never be optimized out.

True.
--
Norman Diamond       diamond@tkov50.enet.dec.com
If this were the company's opinion, I wouldn't be allowed to post it.