[comp.lang.c] const and volatile

dhoward@ready.eng.ready.com (David Howard) (05/18/91)

Questions on const and volatile:

I am using the latest release of the Microtec ANSI C cross compiler, PC hosted,
680x0 target. I am attempting to use const and volatile and getting
results that are slightly different from what I expect. If anyone out ther
has a comment, please do:

const
-----

I declare:

const unsigned char *device = (unsigned char *)0x600000b;

Then I do:

*device = 0x01;

The compiler complains:

'attempt to modify a const'

what I want is for the pointer to be const, but not what it points to!
Basically, I want all my 'consts' in ROM so they won't get trashed, but
I wish to access variable data thru them. I tried various combinations
of parentheses and got nowhere. By the way, the compiler also complains
if I do:

device = (unsigned char *)0x600000d;

but that is what I expect. It doesn't seem right that the declaration should
make BOTH the pointer and the pointee const.

likewise with volatile, I get a reverse situation. I want to point at
a device register that is *really* volatile. In this case I want the 
pointee to be volatile but not the pointer. If I declare the 
pointer:

volatile unsigned char *device = 0x600000e;

the compiler treats BOTH the pointer and pointee as volatile. By that
I mean, when I use the pointer, the compiler always reloads the pointer
itself, and also always reaccesses the dereferenced location. In this
case it works OK, but generates extra code to reload the pointer with
0x600000e every time I use it.

It appears that since the specification of const and volatile is implementation
dependent, the Microtec guys intepreted it in a strange way.            

I guess what I really want is the pointer to be const, and the pointee to
be volatile. Anyone have a suggestion on how to declare the pointer
to get that result? What do other ANSI compilers do?

worley@compass.com (Dale Worley) (05/21/91)

In article <1991May17.213923.17879@ready.eng.ready.com> dhoward@ready.eng.ready.com (David Howard) writes:
   I declare:

   const unsigned char *device = (unsigned char *)0x600000b;

   Then I do:

   *device = 0x01;

   The compiler complains:

   'attempt to modify a const'

   what I want is for the pointer to be const, but not what it points to!

Say: "unsigned char * const device = ...;"  Obvious, isn't it?  :-)

   If I declare the pointer:

   volatile unsigned char *device = 0x600000e;

   the compiler treats BOTH the pointer and pointee as volatile. By that
   I mean, when I use the pointer, the compiler always reloads the pointer
   itself, and also always reaccesses the dereferenced location. In this
   case it works OK, but generates extra code to reload the pointer with
   0x600000e every time I use it.

The compiler is conforming, but it is wasting effort.  Hope that the
next version of the compiler is more efficient.

Dale Worley		Compass, Inc.			worley@compass.com
--
Conspiracy is the opiate of the asses.

steve@taumet.com (Stephen Clamage) (05/22/91)

dhoward@ready.eng.ready.com (David Howard) writes:

>Questions on const and volatile:

>I declare:
>	const unsigned char *device = (unsigned char *)0x600000b;
>Then I do:
>	*device = 0x01;
>The compiler complains:
>	'attempt to modify a const'

The compiler is correct.  You say later that you want the pointer to be
const, not what it points to.  In that case, you need to say this:
	unsigned char * const device = (unsigned char *)0x600000b;
This makes 'device' const, rather than what it points to.  You will
now be able to write
	*device = <something>
but not
	device = <some address>

The same thing applies to volatile, where T is some type:
	volatile T *p;	/* p not volatile, points to a volatile object */
	T * volatile p;	/* p is volatile, the object is not */

For a pointer to a memory-mapped input device or clock, you might want
something like this:
	const volatile T * const p = (const volatile T*) 0xc000abcd;
This says that p cannot be assigned to (it is const), and that it points
to an object which cannot be assigned to, and which might change
spontaneously.  That is:
	p = <some address>;	/* illegal: p is const */
	*p = <some value>;	/* illegal: *p is const */
	a = *p; b = *p;		/* must read p twice, cannot optimize */
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com