[comp.std.c] volatile registers

nevin1@ihlpb.ATT.COM (Liber) (01/04/89)

[followups to comp.std.c]

In article <15171@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes:
>In article <15166@mimsy.UUCP> I suggested that
>... ["register"] implies not-volatile and not-aliased; and it does so
>in a way that the compiler can reasonably enforce.

>You mean to say that a register could be aliased?  Not in C!

This seems to be very similar to the argument about const.  You mean to
say that a (non-volatile) const-qualified object could be modified?  Not
in C!

>How about a volatile register?

I can ask the same question about volatile const.  All the volatile
register means is that the alias to the variable cannot occur within
the conforming C program.

[Side note:  I was skimming through the dpANS C, and the only place I
could find restricting register to being non-aliased is in footnote
#55, section 3.5.1.  Since footnotes aren't an official part of the
Standard, could someone please email me an official reference to this?
If it is not official, then I am asking why not?]

>It is a possibility, but it seems entirely unnecessary.

I agree that I don't see this as being particularly useful; that
doesn't make it illegal, however.

>>A STORAGE CLASS by no means obviates the need for type qualifiers.

>I did not say that.  I said `register implies not-volatile, not-
>aliased': that `volatile register' and `aliased register' are
>nonsensical combinations.

Register only implies non-aliased when not qualified by volatile, in
much the same way that const implies non-modifiable when not qualified
by volatile.  Register is allowed to be aliased by hardware or by a
different thread of execution, but a conforming C program cannot alias
it.

[Another side note:  is it even possible to have a strictly conforming
C program whose behavior would change by declaring any of its
variables volatile?  I cannot think of any examples without having to
escape to having some library routines around that 'cheat'.]
-- 
NEVIN ":-)" LIBER  AT&T Bell Laboratories  nevin1@ihlpb.ATT.COM  (312) 979-4751

dlm@cuuxb.ATT.COM (Dennis L. Mumaugh) (01/04/89)

In      article      <9316@ihlpb.ATT.COM>       nevin1@ihlpb.UUCP
(55528-Liber,N.J.)  makes  some comments about volatile that seem
to reflect many people's understanding.

The concept "volatile" should not occur in any general C program.
This  feature  exists only for the stand alone, the real time and
the kernel hacker.

Its purpose is to state that each  and  every  reference  to  the
volatile  object  [location, structure, register, or whatever] is
necessary and not to optimize such references in any way.

Its only use in a UNIX environment *should* be  with  respect  to
shared  memory  or  mmaped files where more than once process may
access the same location "simultaneously".  I have seen its  need
only  in  writing  drivers  where  a  location actually maps to a
device register and each  referrence  to  the  location  actually
results in the device doing something.  For example:

volatile int foo;
...
foo = 'H';
foo = 'e';
...
foo = 'd';
foo = '.';

might print "Hello world." on the console of the computer if  the
location  "foo"  were  the  output  port for a device controller.
Without the volatile the compiler or the optimizer is allowed  to
reduce the above to

	foo = '.';

In this sense the constuct of a "volatile" register doesn't  make
sense  in the C language as it is not possible to bind a variable
to any specific register [in the instruction set sense].

The question of aliasing is orthoganol to volatile.  It  just  so
happens  that  the  side-effects of declaring a volatile location
result in anti-aliasing of pointers to volatile locations.
-- 
=Dennis L. Mumaugh
 Lisle, IL       ...!{att,lll-crg}!cuuxb!dlm  OR cuuxb!dlm@arpa.att.com

gwyn@smoke.BRL.MIL (Doug Gwyn ) (01/04/89)

In article <9316@ihlpb.ATT.COM> nevin1@ihlpb.UUCP (55528-Liber,N.J.) asks:
>Is it even possible to have a strictly conforming C program whose
>behavior would change by declaring any of its variables volatile?

Declaring a truly non-volatile object as "volatile" would not affect
the virtual-machine semantics, but it would in general have an effect
on code generation (and thus reduce execution speed, etc.).  That's
why it's not the default.

jfh@rpp386.Dallas.TX.US (The Beach Bum) (01/06/89)

In article <2337@cuuxb.ATT.COM> dlm@cuuxb.UUCP (Dennis L. Mumaugh) writes:
>In      article      <9316@ihlpb.ATT.COM>       nevin1@ihlpb.UUCP
>(55528-Liber,N.J.)  makes  some comments about volatile that seem
>to reflect many people's understanding.
>
>The concept "volatile" should not occur in any general C program.
>This  feature  exists only for the stand alone, the real time and
>the kernel hacker.

This is becoming increasing less and less true.  Shared memory
has many applications which should be exploited.


>Its purpose is to state that each  and  every  reference  to  the
>volatile  object  [location, structure, register, or whatever] is
>necessary and not to optimize such references in any way.

Enough said.  Let the programmer beware.

>Its only use in a UNIX environment *should* be  with  respect  to
>shared  memory  or  mmaped files where more than once process may
>access the same location "simultaneously".  I have seen its  need
>only  in  writing  drivers  where  a  location actually maps to a
>device register and each  referrence  to  the  location  actually
>results in the device doing something.

A common usage is in interrupt [ software ] handlers where the
signal catching routine sets a flag and returns.

The proper definition for such a flag should be

in catch.c:
--
int	sigflag;

int	catch (sig)
{
	...
	sigflag = 1;
	...
}
--
then outside catch.c you must use

extern	volatile int sigflag;

I am wondering how many programs will get this right when the
ANSI compilers invade our lives.  Or, how many program get
it right NOW?  I bet the number is virtually identical ...
-- 
John F. Haugh II                        +-Quote of the Week:-------------------
VoiceNet: (214) 250-3311   Data: -6272  |"Anything on the road which can be
InterNet: jfh@rpp386.Dallas.TX.US       | hit, will be ..."
UucpNet : <backbone>!killer!rpp386!jfh  +--------------------------------------

beyer@houxs.ATT.COM (J.BEYER) (01/06/89)

In article <2337@cuuxb.ATT.COM>, dlm@cuuxb.ATT.COM (Dennis L. Mumaugh) writes:
> In      article      <9316@ihlpb.ATT.COM>       nevin1@ihlpb.UUCP
> (55528-Liber,N.J.)  makes  some comments about volatile that seem
> to reflect many people's understanding.
> 
> The concept "volatile" should not occur in any general C program.
> This  feature  exists only for the stand alone, the real time and
> the kernel hacker.
>
I disagree with this statement.
Consider a program with a global variable that can be accessed by the
'main' program and a signal handler. On receipt of the signal, the
signal handler might change the value of the global variable. When the
signal handler returns, the 'main' program might observe the value of
the global variable. Were this variable not declared volatile, the main
program's code might be optimized so that the changed value would not
be detected. Were the main program be stuck in a 'busy-loop' waiting
for the global variable to change, and an optimizer (or clever compiler)
optimized the test outside the loop, the main program would never get out.
You may not care for this programming style, but it is legal and it is done.
 
-- 
Jean-David Beyer
A.T.&T., Holmdel, New Jersey, 07733
houxs!beyer

chris@mimsy.UUCP (Chris Torek) (01/06/89)

>In article <2337@cuuxb.ATT.COM> dlm@cuuxb.ATT.COM (Dennis L. Mumaugh) writes:
>>The concept "volatile" should not occur in any general C program.
>>This feature exists only for the stand alone, the real time and
>>the kernel hacker.

In article <1103@houxs.ATT.COM> beyer@houxs.ATT.COM (J.BEYER) writes:
>I disagree with this statement.
>Consider a program with a global variable that can be accessed by the
>'main' program and a signal handler. ...

I forget whether using signal handlers and `sig_atomic_t' gives a
strictly conformant program.  Note, though, that in this case the
variable cannot be declared `register' as it is global or static.
[see subject: header]

(This, and setjmp/longjmp, are probably the only two places where
strictly conformant programs need the volatile qualifier.  I believe
that the qualifier, if present, is hidden underneath the sig_atomic_t
typedef.)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

blm@cxsea.UUCP (Brian Matthews) (01/07/89)

The Beach Bum (jfh@rpp386.Dallas.TX.US) writes:
|A common usage is in interrupt [ software ] handlers where the
|signal catching routine sets a flag and returns.
|
|The proper definition for such a flag should be
|
|in catch.c:
|--
|int	sigflag;
|
|int	catch (sig)
|{
|	...
|	sigflag = 1;
|	...
|}
|--
|then outside catch.c you must use
|
|extern	volatile int sigflag;

The spirit of the posting is correct, but there are a couple of technical
errors.

First, the type of sigflag should be sig_atomic_t, not int.  Second, as
the function argument to signal is void (*fn)(int), catch should be a
void function.  See the signal handling section of the draft (section
4.7, I believe).

-- 
Brian L. Matthews  blm@cxsea.UUCP   ...{mnetor,uw-beaver!ssc-vax}!cxsea!blm
+1 206 251 6811    Computer X Inc. - a division of Motorola New Enterprises

dlm@cuuxb.ATT.COM (Dennis L. Mumaugh) (01/07/89)

In article <10720@rpp386.Dallas.TX.US> jfh@rpp386.Dallas.TX.US 
(The Beach Bum) writes:
>Shared memory has many applications which should be exploited.

As I alluded to in my article.   Actually shared memory has so many
pitfalls, even volatile isn't safe.   The WE32100 has a swapi
instruction that can be used for concurrency applications.  Guess
what?  Co-processors and caches do strange things then.   I think
volatile is a very dangerous construct and can and will bite the user
unless s/he is VERY carefull.
>
>A common usage is in interrupt [ software ] handlers where the
>signal catching routine sets a flag and returns.
>
I received a lot of mail about this use.   It is marginally
acceptable.   It is only necessary with aggressive optimizers
that do strength reductions on while loops and the user does
a 
	while( ! intflag) sleep(10);
type of construct.   Surely there are other better techniques.

I also saw comments that the constuct of a volatile register
was useful in setjmp/longjmp to preserve a register.  Perhaps
Doug Gwyn can comment whether this was accepted by ANSI or not.

Any other use of a volatile register is not meaningful unless one uses
lightweight/multithread processes sharing registers and doing
concurrent execution and that is sufficently mindboggling that I'd
program it in a decent language like NELIAC  [ half seriously now!].

-- 
=Dennis L. Mumaugh
 Lisle, IL       ...!{att,lll-crg}!cuuxb!dlm  OR cuuxb!dlm@arpa.att.com

bill@twwells.uucp (T. William Wells) (01/07/89)

In article <9316@ihlpb.ATT.COM> nevin1@ihlpb.UUCP (55528-Liber,N.J.) writes:
: [Side note:  I was skimming through the dpANS C, and the only place I
: could find restricting register to being non-aliased is in footnote
: #55, section 3.5.1.  Since footnotes aren't an official part of the
: Standard, could someone please email me an official reference to this?
: If it is not official, then I am asking why not?]

It doesn't have to say this. To alias something, one must have its
address.  Registers can't have their addresses taken. Therefore
register variables can't be aliased. QED.

: [Another side note:  is it even possible to have a strictly conforming
: C program whose behavior would change by declaring any of its
: variables volatile?

No. Volatile might change the way the compiler generates code.  And
that may change the way that the compiler handles implementation
defined parts of the language. However, by definition, a strictly
conforming C program can't behave differently because of something
implementation defined.  Thus, if a program were to change because of
the volatile keyword, it wouldn't have been a strictly conforming
program in the first place.

---
Bill
{ uunet!proxftl | novavax } !twwells!bill

wendyt@pyrps5 (Wendy Thrash) (01/11/89)

In article <298@twwells.uucp> bill@twwells.UUCP (T. William Wells) writes:
>To alias something, one must have its
>address.  Registers can't have their addresses taken. Therefore
>register variables can't be aliased. QED.

If the above is a statement about register variables in standard-conforming C
programs, it may be true; if it's a statement about computer hardware, it
is false.  On Pyramid hardware, for example,  one is quite free to take the
addresses of registers (though it takes a couple of instructions to do so).
Our current implementation of C also allows taking the address of a register
variable, remarking as it does that,
"warning: taking the address of a register variable is not portable".

We now have a proof and a counterexample.

bill@twwells.uucp (T. William Wells) (01/11/89)

In article <54573@pyramid.pyramid.com> wendyt@pyrps5.UUCP (Wendy Thrash) writes:
: In article <298@twwells.uucp> bill@twwells.UUCP (T. William Wells) writes:
: >To alias something, one must have its
: >address.  Registers can't have their addresses taken. Therefore
: >register variables can't be aliased. QED.
:
: If the above is a statement about register variables in standard-conforming C
: programs, it may be true; if it's a statement about computer hardware, it
: is false.  On Pyramid hardware, for example,  one is quite free to take the
: addresses of registers (though it takes a couple of instructions to do so).
: Our current implementation of C also allows taking the address of a register
: variable, remarking as it does that,
: "warning: taking the address of a register variable is not portable".
:
: We now have a proof and a counterexample.

It's about register variables in a standard-conforming program.

I know of one machine where registers are indistinguishable from a
certain area of memory. One could even store instructions in the
registers and branch there!  And on several micro compilers, register
is interpreted to mean "put this into fast memory" (they don't have
any registers useful for storing C variables).

---
Bill
{ uunet!proxftl | novavax } !twwells!bill