limiting access to a variable...

A

Antonio

I'm developing the firmware for a slave in a comunication channel. Now
there is certain information (namely the addresses of the slave and the
master) that must be changeable while the device is up and operating.
The obvious choice is to store the addresses in some variable. But I
would like to prevent unintentional changes in those variables so I
thought of doing the following stuff:

File addresses.c :

char masterAddress;

void changeMasterAddress (char newValue) {
masterAddress = newValue;
}


Another file:

extern const volatile char masterAddress;
extern void changeMasterAddress (char newValue);

I've compiled this with gcc and it works as expected. The compiler
issues warnings if I try to assign a value to masterAddress outside
addresses.c, and I can still change its value with changeMasterAddress
anywhere in the code.

Finally my questions:
1.- Is this behaviour standard?
2.- Is the volatile keyword needed in the declaration? I thought of
placing it to prevent the compiler from optimizing multiple accesses to
a read-only variable (as seen in the rest of the files).

Thanks in advance.
 
T

Tim Rentsch

Antonio said:
I'm developing the firmware for a slave in a comunication channel. Now
there is certain information (namely the addresses of the slave and the
master) that must be changeable while the device is up and operating.
The obvious choice is to store the addresses in some variable. But I
would like to prevent unintentional changes in those variables so I
thought of doing the following stuff:

File addresses.c :

char masterAddress;

void changeMasterAddress (char newValue) {
masterAddress = newValue;
}


Another file:

extern const volatile char masterAddress;
extern void changeMasterAddress (char newValue);

I've compiled this with gcc and it works as expected. The compiler
issues warnings if I try to assign a value to masterAddress outside
addresses.c, and I can still change its value with changeMasterAddress
anywhere in the code.

Finally my questions:
1.- Is this behaviour standard?
2.- Is the volatile keyword needed in the declaration? I thought of
placing it to prevent the compiler from optimizing multiple accesses to
a read-only variable (as seen in the rest of the files).

This approach isn't the way to do what you want.

To prevent accesses to masterAddress from outside the
addresses.c compilation unit, make it 'static':

static char masterAddress;

This declaration prevents all accesses outside the single
compilation unit (addresses.c). If you want to allow read
access but disallow write access, C doesn't provide an easy
way to do that; so, if that's what you want to do, you can
add this declaration to addresses.c:

const char * const masterAddress_p = &masterAddress;

and for other compilations units that you want to use the
variable:

extern const char * const masterAddress_p;

The value of the variable masterAddress may now be accessed
(for reading, not for writing) with '*masterAddress_p'.
Inside addresses.c, the variable 'masterAddress' may be
assigned to directly, which will result in changing the
value of '*masterAddress_p'.

The idea of declaring the variable 'const volatile' just in
the extern declarations is no good; some implementations
may do the right thing with this approach, but strictly
speaking it results in undefined behavior.
 
A

Antonio

Tim said:
This approach isn't the way to do what you want.

To prevent accesses to masterAddress from outside the
addresses.c compilation unit, make it 'static':

static char masterAddress;

This declaration prevents all accesses outside the single
compilation unit (addresses.c). If you want to allow read
access but disallow write access, C doesn't provide an easy
way to do that; so, if that's what you want to do, you can
add this declaration to addresses.c:

const char * const masterAddress_p = &masterAddress;

and for other compilations units that you want to use the
variable:

extern const char * const masterAddress_p;

The value of the variable masterAddress may now be accessed
(for reading, not for writing) with '*masterAddress_p'.
Inside addresses.c, the variable 'masterAddress' may be
assigned to directly, which will result in changing the
value of '*masterAddress_p'.

Thanks a lot. I like your approach much more.
The idea of declaring the variable 'const volatile' just in
the extern declarations is no good; some implementations
may do the right thing with this approach, but strictly
speaking it results in undefined behavior.

Why is it so? (Besides the fact that the standard says so.)
 
K

Kenneth Brody

Antonio said:
Tim said:
extern const volatile char masterAddress;
[...]
The idea of declaring the variable 'const volatile' just in
the extern declarations is no good; some implementations
may do the right thing with this approach, but strictly
speaking it results in undefined behavior.

Why is it so? (Besides the fact that the standard says so.)

What, exactly, is "const volatile" supposed to mean? "Const" means
that it doesn't change, and "volatile" means that it may change
without you doing anything.

I am guessing that you want it to mean "this is a volatile variable,
but _I_ am not allowed to change it"?

What does the standard say about this, anyway?

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:[email protected]>
 
S

Suman

Kenneth said:
Antonio said:
Tim said:
extern const volatile char masterAddress; [...]
The idea of declaring the variable 'const volatile' just in
the extern declarations is no good; some implementations
may do the right thing with this approach, but strictly
speaking it results in undefined behavior.

Why is it so? (Besides the fact that the standard says so.)

What, exactly, is "const volatile" supposed to mean? "Const" means
that it doesn't change, and "volatile" means that it may change
without you doing anything.

I am guessing that you want it to mean "this is a volatile variable,
but _I_ am not allowed to change it"?

What does the standard say about this, anyway?
`const' and `volatile' are both type qualifiers, and it is
perfectly legal to have them both.

There is an example in the (C99) draft of the same, and this is what
it says:
"An object declared
extern const volatile int real_time_clock;
may be modifiable by hardware, but cannot be assigned to, incremented,
or decremented."

Does that help?
 
T

Tim Rentsch

Antonio said:
[snip]

Thanks a lot. I like your approach much more.

You're welcome. Glad it worked for you.

Why is it so? (Besides the fact that the standard says so.)

Basically, all declarations of a variable need to be the
same. (The technical phrase is that "their types need to
be compatible", which isn't quite the same as "the same",
but the details of how they are different isn't important
here.)

The reason all declarations need to be the same is that
if they were different, different compilation units might
make different assumptions about how to make use of the
variables. For example, 'const' variables might be put
in special read-only memory; if a variable were 'const'
in one compilation unit and not in another, that would
probably cause problems under such a scheme.

Of course, it would have been possible to come up with a
rule to deal with these situations. But the rule would
likely be extremely complicated, and impose constraints
on compilers and so forth that wouldn't otherwise be
there; moreover, the benefits would likely be extremely
small. Rather than add all that complication for little
benefit, instead a decision was made to require each
variable to have compatible declarations everywhere it
was used.
 
G

Gordon Burditt

What, exactly, is "const volatile" supposed to mean? "Const" means
that it doesn't change, and "volatile" means that it may change
without you doing anything.

I am guessing that you want it to mean "this is a volatile variable,
but _I_ am not allowed to change it"?

What does the standard say about this, anyway?

I believe one of the standard examples is:

const volatile time_t *hardware_real_time_clock = <some magic address here>;

which represents a pointer to a hardware register YOU can't change,
but which changes all by itself. The same typically applies to
memory-mapped IO "status registers" which are read-only. Or, for
that matter, they might apply to memory-mapped IO "data registers"
which, as soon as you read it, load up the next character available
if there is one.

const doesn't mean constant. A const variable is not a
valid constant expression. The declaration:
ant const int bar = 42;

switch (c) {
case bar: ...;
default: ...;
...
}

was removed from the C standard retroactively by undefined behavior
caused by void main on a DS9K with the time-travel add-on.


Gordon L. Burditt
 
L

Lawrence Kirby

Antonio said:
Tim said:
extern const volatile char masterAddress; [...]
The idea of declaring the variable 'const volatile' just in
the extern declarations is no good; some implementations
may do the right thing with this approach, but strictly
speaking it results in undefined behavior.

Why is it so? (Besides the fact that the standard says so.)

What, exactly, is "const volatile" supposed to mean? "Const" means
that it doesn't change, and "volatile" means that it may change
without you doing anything.

const means read-only or "I can't change it". volatile means "something
else can change it without my knowledge". const volatile means I
can't change it but something else can.
I am guessing that you want it to mean "this is a volatile variable,
but _I_ am not allowed to change it"?

That's pretty much what it is.

Lawrence
 

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