Use of the Volatile keyword for a pointer to a volatile memory block

B

ben

Hello All,

I am trying to make sense of a bit of syntax, is there a guru out
there that can clear this up for me.

I have a buffer declared as

static volatile u8 buffer;

and I have a pointer to that buffer declared as

static volatile u8 * volatile pBuffer;

pBuffer = &buffer; // easy right

What I am trying to achieve is to create a pointer to a buffer. I want
the pointer to be volatile and I want the buffer it is pointing to to
be volatile.

The reason I am doing this is to apply the misra guidlines so I am
already aware that becuase the pointer is volatile the code will be
forced to dereference each time it is used.

The declarations above work okay, compile and run, but I cannot
understand why the second volatile apears between the type and name "*
volatile pBuffer". If I place it before the type

static volatile u8 volatile * pBuffer; // this fails

it doesnt work. but keywords appear before the type dont they ?

Also, it may just be the crappy compiler i am using but if I declare
the pointer as a constant, pointing at a volatile buffer,

static const u8 * volatile pBuffer;

I seem to be able to assign the pointer a value at run time. This
makes no sense to me.

Can anyone add parentheis to my declarations so I can read my own code
and feel sure the volatile keyword is doing what I want it to do ?

Thanks all in advance.
 
D

dandelion

static volatile u8 buffer;
static volatile u8 * volatile pBuffer;

pBuffer = &buffer; // easy right

The declarations above work okay, compile and run, but I cannot
understand why the second volatile apears between the type and name "*
volatile pBuffer". If I place it before the type

static volatile u8 volatile * pBuffer; // this fails

it doesnt work. but keywords appear before the type dont they ?

Not always. This case is one exception. In this case the content of the
buffer is volatile. That is, the object your pointer is pointing *at* is
volatile, not the actual pointer to it.
Also, it may just be the crappy compiler i am using but if I declare
the pointer as a constant, pointing at a volatile buffer,

static const u8 * volatile pBuffer;

I seem to be able to assign the pointer a value at run time. This
makes no sense to me.

Actually it does. The *pointer* is constant, but the object *pointed at*
isn't. So the declaration makes perfect sense.

HTH dandelion.
 
U

Ulrich Eckhardt

ben said:
static volatile u8 buffer;
static volatile u8 * volatile pBuffer;
pBuffer = &buffer; // easy right [...]
The declarations above work okay, compile and run, but I cannot
understand why the second volatile apears between the type and name "*
volatile pBuffer". If I place it before the type

static volatile u8 volatile * pBuffer; // this fails

it doesnt work. but keywords appear before the type dont they ?

No, that's just the exception. cv-qualifiers (vc meaning 'constant
volatile', as they are basically handled the same way) always appear after
the thing they apply to, with the exception that if they are on the
leftmost side of a declaration they apply to the thing on their right.

So:
volatile u8* ptr; // exception
u8 volatile* ptr; // canonical form

For variable declarations, the rule is to read the thing from the right to
the left, like "ptr is a pointer to a volatile u8". So if you want a
volatile pointer to an const double you would use
double const* volatile pd;

Don't ask me why people still use the exceptional way instead of wrapping
their minds around the canonical form. This was and still is the source of
heated discussion that usually generates more heat than light; I won't
dive too deep into this argument...
Also, it may just be the crappy compiler i am using but if I declare
the pointer as a constant, pointing at a volatile buffer,

static const u8 * volatile pBuffer;

I seem to be able to assign the pointer a value at run time. This
makes no sense to me.

There is not const pointer here, just a volatile pointer to a const u8.

Uli
 
C

Chris Torek

... cv-qualifiers (cv meaning 'constant volatile', as they are
basically handled the same way) always appear after the thing
they apply to, with the exception that if they are on the leftmost
side of a declaration they apply to the thing on their right.

So:
volatile u8* ptr; // exception
u8 volatile* ptr; // canonical form

For variable declarations, the rule is to read the thing from the right to
the left, like "ptr is a pointer to a volatile u8". So if you want a
volatile pointer to an const double you would use
double const* volatile pd;

Don't ask me why people still use the exceptional way instead of wrapping
their minds around the canonical form. ...

Probably because "const" and "volatile" *look* like storage-class
specifiers, and "static int i = 3" is more common than "int static
i = 3".

(I have in the past argued that const should have been an sc-specifier,
and I still think this would be less confusing and more consistent;
but "volatile" actually does make sense as a type-qualifier, since
a pointer and its target may well both be "things secretly fiddled
by hardware behind the compiler's back".)
 
L

Lawrence Kirby

ben said:
static volatile u8 buffer;
static volatile u8 * volatile pBuffer;
pBuffer = &buffer; // easy right [...]
The declarations above work okay, compile and run, but I cannot
understand why the second volatile apears between the type and name "*
volatile pBuffer". If I place it before the type

static volatile u8 volatile * pBuffer; // this fails

it doesnt work. but keywords appear before the type dont they ?

No, that's just the exception. cv-qualifiers (vc meaning 'constant
volatile', as they are basically handled the same way) always appear after
the thing they apply to, with the exception that if they are on the
leftmost side of a declaration they apply to the thing on their right.

Type specifier/qualifiers/storage class specifiers and inline in C99 can
appear in any order, so that isn't entirely correct.
So:
volatile u8* ptr; // exception
u8 volatile* ptr; // canonical form

Only according to your specification of how the canonocal form should be
constructed. The more normal canonocal form is:

volatile u8 *ptr;
For variable declarations, the rule is to read the thing from the right
to the left, like "ptr is a pointer to a volatile u8".

Not true in general when arrays or functions are involved. The correct
analysis of a declarator is a syntactic one, similar to the analysis of an
expression. Right to left is misleading, although it works some of the
time.
So if you want a
volatile pointer to an const double you would use
double const* volatile pd;

I would advocate writing that as

const double *volatile pd;

because it makes it clear that the volatile is related to the pointer, and
follows the natural syntax of the declaration. Also the declaration
specifiers aren't saying that we have a double const (what's that,
something that's very const?), we have a const double. The fact is that I
read C declarations left to right just like everything else. That doesn't
stop me being able to parse a declarator correctly just as I can parse an
expression correctly.
Don't ask me why people still use the exceptional way instead of
wrapping their minds around the canonical form.

I won't ask you about people, but I could ask you why you use the
exceptional, non-canonical form. :)

Sometimes there is an obvious minimal/simplest form which can be
considered canonical. In this case there isn't. Sometimes there is a
commonly agreed upon form that is considered or indeed defined as
canonical. Here there is no form that is agreed upon, so it is arguable
whether the concept of canonical form is applicable here or if it
is whether it means any more than "preferred style". If there is a
canonical form it would be reasonabe to base a definition on "what best
describes/follows the syntax."
This was and still is
the source of heated discussion that usually generates more heat than
light; I won't dive too deep into this argument...


There is not const pointer here, just a volatile pointer to a const u8.

Since the pointer is not const it is reasonable to be about to assign a
value to it.

Lawrence
 
U

Ulrich Eckhardt

Lawrence said:
Not true in general when arrays or functions are involved. The correct
analysis of a declarator is a syntactic one, similar to the analysis
of an expression. Right to left is misleading, although it works some
of the time.

Right, I should have said 'a simple rule of thumb is'.
So if you want a
volatile pointer to an const double you would use
double const* volatile pd;

I would advocate writing that as

const double *volatile pd;

because it makes it clear that the volatile is related to the
pointer, and follows the natural syntax of the declaration.
Also the declaration specifiers aren't saying that we have a double
const [...], we have a const double.

You are mixing English with C here. There are languages where an attribute
like 'constant' appears after the object that is constant, just because
your language puts it before the object doesn't mean C should.
The fact is that I read C declarations left to right just like everything
else. That doesn't stop me being able to parse a declarator correctly
just as I can parse an expression correctly.

Reading it from right to left is "like a finger pointing at the moon. Once
you see the moon, you don't need the finger any more." IOW, you are one
step closer to understanding C syntax that those that need the mentioned
rule of thumb. ;)
I won't ask you about people, but I could ask you why you use the
exceptional, non-canonical form. :)

Hmmm. If you count all the cases of variable declarations where the CV
qualifier can be on the right side of what it is associated with and the
cases where it can be on its left, you will find there are more cases
where it can be on the right. In fact in every case it can be on the
right, but only in a few cases it can be on the left.

I don't get how you can call the only way that always works
exceptional. ;-)

Uli
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,767
Messages
2,569,570
Members
45,045
Latest member
DRCM

Latest Threads

Top