473,397 Members | 2,033 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,397 software developers and data experts.

cast to volatile

Hello,

even (or because?) reading the standard (ISO/IEC 9899/1999) I do not
understand some issues with volatile. The background is embedded
programming where data is exchanged between main program flow and
interrupts.

At the organisation I work, instead of declaring a variable volatile,
it is casted to volatile when necessary:

Example 1 (reading):
int flag; // global variable, non-volatile
while( (volatile)flag ) // cast to volatile before reading
;

The reason for this is: when the variable is declared volatile, the
compiler cannot optimize it at all. However, by using the cast to
volatile, one can force volatile behavior in some areas, while others
(e.g. in the interrupt) still can be optimized. Addionally, this can be
used even if the variable declaration is not under my control.

Question: is this covered by the standard?

Since the whole topic of volatile is very complex (e.g. it is related
to pipeling), does somebody know a good article or book which covers
this topic deeply?

BTW, does anybody know how to google an expression like (volatile)
(*including* the bracket)?

Thanks,

Uli G. Margull

nospam@"lastname".de

Nov 14 '05 #1
14 19187
go***************@margull.de writes:
Hello,

even (or because?) reading the standard (ISO/IEC 9899/1999) I do not
understand some issues with volatile. The background is embedded
programming where data is exchanged between main program flow and
interrupts.

At the organisation I work, instead of declaring a variable volatile,
it is casted to volatile when necessary:

Example 1 (reading):
int flag; // global variable, non-volatile
while( (volatile)flag ) // cast to volatile before reading
;

The reason for this is: when the variable is declared volatile, the
compiler cannot optimize it at all. However, by using the cast to
volatile, one can force volatile behavior in some areas, while others
(e.g. in the interrupt) still can be optimized. Addionally, this can be
used even if the variable declaration is not under my control.
This method doesn't do what you want, which is to say it doesn't
force volatile semantics. Use this instead:

while( *(volatile*) &flag ) ...

Question: is this covered by the standard?
Yes, although perhaps not as directly as it might.

Since the whole topic of volatile is very complex (e.g. it is related
to pipeling), does somebody know a good article or book which covers
this topic deeply?


A small set of rules for using volatile:

1. Use volatile for variables that might change "unexpectedly".

2. Use volatile for automatic variables in routines that use
setjmp().

3. To force volatile semantics on a particular access, take the
address of the variable and cast it to (volatile WHATEVER *),
dereferencing the cast expression to get the value.

4. Sometimes volatile is a reasonable way to get around problems
with code generation in compilers that have conformance
problems in some areas, eg, the gcc compiler on x86 with
semantics of assigning or casting to double. Don't do
this just haphazardly, since if it's unnecessary code
quality will very likely go down.

5. Unless you really know what you're doing and why you're
doing it, if you're using volatile you're likely doing
something wrong. Try to find another way to solve the
problem, and if you still have to use volatile code
up a nice small example and post to comp.lang.c and
ask for helpful suggestions.

Nov 14 '05 #2
Tim Rentsch <tx*@alumnus.caltech.edu> writes:
This method doesn't do what you want, which is to say it doesn't
force volatile semantics. Use this instead:

while( *(volatile*) &flag ) ...


Of course what I meant to write was

while( *(volatile int*) &flag ) ...
Nov 14 '05 #3
On Thu, 16 Jun 2005 00:18:03 -0700, google-newsgroups wrote:
Hello,

even (or because?) reading the standard (ISO/IEC 9899/1999) I do not
understand some issues with volatile. The background is embedded
programming where data is exchanged between main program flow and
interrupts.

At the organisation I work, instead of declaring a variable volatile,
it is casted to volatile when necessary:

Example 1 (reading):
int flag; // global variable, non-volatile
while( (volatile)flag ) // cast to volatile before reading
;
I assume you mean the cast (volatile int)flag. This doesn't do what you
want. The special behaviour of the const and volatile qualifiers only
applies to lvalues (although type rules apply in other situations). What
the code above does is read the value of flag using non-volatile semantics
then casts that value to volatile int. Since it 9is just a value at this
point and not an lvalue the volatile has no effect. The line is equivalent
to

while (flag)

You would have to write something like

while (*(volatile int *)&flag)

to do what you want. Here the *lvalue* used to read the value of flag has
type volatile int.
The reason for this is: when the variable is declared volatile, the
compiler cannot optimize it at all. However, by using the cast to
volatile, one can force volatile behavior in some areas, while others
(e.g. in the interrupt) still can be optimized.
The whole concept of using a volatile variable as non-volatile in some
areas sounds dangerous. You would probably be better off using a separate
variable for parts that don't need to be volatile. That could make the
compiler optimiser's job easier too.
Addionally, this can be
used even if the variable declaration is not under my control.
It sounds like an odd situation. A variable being used in this way should
be defined as volatile. If it isn't that suggests the code defining it
isn't designed for this purpose and probably won't work properly.
Question: is this covered by the standard?
The standard specifies volatile
Since the whole topic of volatile is very complex (e.g. it is related
to pipeling), does somebody know a good article or book which covers
this topic deeply?


volatile itself has nothing to do with pipelining. How volatile might be
implemented on specific architectures is a machine code level topic. If
you are writing in C you let the compiler handle the details.

Also consider the sig_atomic_t type.

Lawrence
Nov 14 '05 #4
Tim Rentsch wrote:

Tim Rentsch <tx*@alumnus.caltech.edu> writes:
This method doesn't do what you want, which is to say it doesn't
force volatile semantics. Use this instead:

while( *(volatile*) &flag ) ...


Of course what I meant to write was

while( *(volatile int*) &flag ) ...


Doesn't (volatile*) mean the same thing as (volatile int*)?

--
pete
Nov 14 '05 #5
Thanks for your answers sofar. In the meantime, I tested the problem on
a PowerPC platform with a Wind River compiler, with the following
results:

int dummy = 0;

1.
unsigned char flag;
while( (volatile)flag)
dummy++;

The above does not work: the memory is not reloaded in the evaluation

2.
unsigned char flag;
while( (volatile unsigned char)flag )
dummy++;

The above does work: the memory is reloaded every time

3.
unsigned int flag;
while( (volatile unsigned char)flag )
dummy++;

The above does not work: the memory is not reloaded.

At the moment, the proposed solution in the company is to use the
second one (volatile unsigned char), but I see problems with conformity
to ANSI-C.

Thanks again & regards,

Uli Margull

Nov 14 '05 #6
pete <pf*****@mindspring.com> writes:
Tim Rentsch wrote:

Tim Rentsch <tx*@alumnus.caltech.edu> writes:
This method doesn't do what you want, which is to say it doesn't
force volatile semantics. Use this instead:

while( *(volatile*) &flag ) ...


Of course what I meant to write was

while( *(volatile int*) &flag ) ...


Doesn't (volatile*) mean the same thing as (volatile int*)?


Yes I believe it does, but in C99 I think it may require a diagnostic.
In any case I consider '(volatile int*)' to be better style.
Nov 14 '05 #7
On Thu, 16 Jun 2005 10:08:22 +0000, pete wrote:
Tim Rentsch wrote:

Tim Rentsch <tx*@alumnus.caltech.edu> writes:
> This method doesn't do what you want, which is to say it doesn't
> force volatile semantics. Use this instead:
>
> while( *(volatile*) &flag ) ...


Of course what I meant to write was

while( *(volatile int*) &flag ) ...


Doesn't (volatile*) mean the same thing as (volatile int*)?


It did in C90, but C99 has outlawed "implicit int".

Lawrence
Nov 14 '05 #8
On Thu, 16 Jun 2005 05:16:22 -0700, google-newsgroups wrote:
Thanks for your answers sofar. In the meantime, I tested the problem on
a PowerPC platform with a Wind River compiler, with the following
results:

int dummy = 0;

1.
unsigned char flag;
while( (volatile)flag)
dummy++;
A non-volatile access of flag
The above does not work: the memory is not reloaded in the evaluation

2.
unsigned char flag;
while( (volatile unsigned char)flag )
dummy++;
Another non-volatile access of flag
The above does work: the memory is reloaded every time
A compiler may choose to implement any object access as volatile if it
wishes, however that doesn't make the code correct.
3.
unsigned int flag;
while( (volatile unsigned char)flag )
dummy++;
Agaon, a non-volatile access of flag.
The above does not work: the memory is not reloaded.

At the moment, the proposed solution in the company is to use the second
one (volatile unsigned char), but I see problems with conformity to
ANSI-C.


A couple of people have given a correct solution, why are you considering
3 wrong solutions and ignoring that?

And, again, consider using sig_atomic_t for the integer type.

Lawrence
Nov 14 '05 #9
Lawrence Kirby wrote:

On Thu, 16 Jun 2005 10:08:22 +0000, pete wrote:

Doesn't (volatile*) mean the same thing as (volatile int*)?


It did in C90, but C99 has outlawed "implicit int".


Thank you.

--
pete
Nov 14 '05 #10
Tim Rentsch wrote:

pete <pf*****@mindspring.com> writes:

Doesn't (volatile*) mean the same thing as (volatile int*)?


Yes I believe it does, but in C99 I think it may require a diagnostic.
In any case I consider '(volatile int*)' to be better style.


Thank you.
I think so too.

I think it's best to write in a style constrained by both
C89 and C99.

int main(void){return 0;}
instead of
main(){return 0;}
or
int main(void){}

--
pete
Nov 14 '05 #11
Hi Lawrence,

thank you everybody for writing your discussion topics, and I assure
you that I am not ignoring any post.

In the company I work (it's a rather big one), the coding guidelines
state that the "cast" to (volatile int) is the correct way to access a
variable that might change from outside (e.g. due to ISR).

In order to change that rule, I do not only have to know what is right
or wrong, but I need an rock-solid argument proving my opinion.
Basically, I have to argue out of the standard. However, I personally
have a hard time reading this from the standard.

Again, thanks for all your posts, and I am not ignoring them.

Yours,

Uli Margull

Nov 14 '05 #12
go***************@margull.de writes:
In the company I work (it's a rather big one), the coding guidelines
state that the "cast" to (volatile int) is the correct way to access a
variable that might change from outside (e.g. due to ISR).

In order to change that rule, I do not only have to know what is right
or wrong, but I need an rock-solid argument proving my opinion.
Basically, I have to argue out of the standard. However, I personally
have a hard time reading this from the standard.


I recommend the Rationale document ("Rationale for International
Standard--Programming Languages--C"). In particular, if people
need convincing, quote this paragraph out of section 6.7.3 of the
Rationale document:

A cast of a value to a qualified type has no effect; the
qualification (volatile, say) can have no effect on the access
sinceit has occurred prior to the case. If it is necessary to
access a non-volatile object using volatile semantics, the
technique is to cast the address of the object to the appropriate
pointer-to-qualified type, then dereference that pointer.

Notice the last sentence. In other words, use:

* (volatile WHATEVER *) & non_volatile_object_identifier

The paragraph in question is just before section 6.7.3.1 in the
rationale document. If you also need to quote from the standard
document itself, cite 6.7.3 p3:

The properties associated with qualified types are meaningful
only for expressions that are lvalues.

The expression

(volatile WHATEVER) non_volatile_object_identifier

is _not_ an lvalue, hence the 'volatile' qualifier is meaningless.
Conversely, the expression

* (volatile WHATEVER *) & non_volatile_object_identifier

_is_ an lvalue (it may be placed on the left side of an assignment
statement), so the property of the 'volatile' qualifier has its
intended meaning in this case.

Nov 14 '05 #13
Hi Tim,

thanks a lot. I think this solved my problem.

Now I am looking forward to some interesting discussions here...

Yours,

Uli

Nov 14 '05 #14
In article <11**********************@g47g2000cwa.googlegroups .com>
<go***************@margull.de> wrote:
Thanks for your answers sofar. In the meantime, I tested the problem on
a PowerPC platform with a Wind River compiler ...
It may be worth noting that there is more than one Wind River
compiler for PowerPC platforms. This is about all that is
at least marginally on-topic here; the rest probably belongs
in comp.os.vxworks.

[In all three examples, "flag" is a non-volatile object, which
will presumably be modified from an interrupt handler. The first
two make it an "unsigned char" and the third an "unsigned int".]
while( (volatile)flag) [does not work as desired]
while( (volatile unsigned char)flag ) [does work as desired]
while( (volatile unsigned char)flag ) [does not work as desired] At the moment, the proposed solution in the company is to use the
second one (volatile unsigned char), but I see problems with conformity
to ANSI-C.


While none of these is "nonstandard", the fact that the second one
happens to work under whatever conditions you have used to test it
is probably mere coincidence.

The *best* solution is to declare "flag" as volatile in the first
place. The second best is to use *(volatile T *)&flag, where T
stands for the actual type of "flag" (unsigned char or unsigned int).
The former will work on all the Wind River compilers, and the latter
will work in all the cases I am aware of (which is nowhere near
"all").
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: newsock | last post by:
Why need to qualify a member function "volatile"? Why need to qualify a object "volatile"? When need to "const_cast" away "volatile" of an object and a member function? I also saw some code...
8
by: Tim Rentsch | last post by:
Here's another question related to 'volatile'. Consider the following: int x; void foo(){ int y; y = (volatile int) x;
6
by: LBJ | last post by:
lets say i have the following definition: volatile char* p = 0x0a0a0a; lets say p now points directly to cacheable memory, and lets also say that this memory is currently cached. when p is...
6
by: Tim | last post by:
I'm trying to co-erce a __gc array of Byte to a __nogc pointer to char to pass to a native function call in a bit of managed c++ code like this: Byte field __gc = dynamic_cast<Byte...
23
by: steve.j.donovan | last post by:
Hi guys, We have the following macro: #define NEXT(type,p) (*((type*)(p))++) It provides a way to poke variable sized data into an array of pcode for a simple VM. e.g,
18
by: Mark | last post by:
Hi List, I want to write a function to copy some data out of a hardware buffer. The hardware can change the contents of this buffer without it being written to by my function. I want to use...
6
by: red floyd | last post by:
I have a struct that maps onto a set of memory mapped registers. I access this via a pointer. Is it better to declare it as pointer to a volatile struct, or to declare the individual members as...
18
by: Felix Kater | last post by:
I haven't been thinking about it for years but recently I've stumbled on the fact that 'casting' is actually doing (at least) two different things: On the one hand 'casting' means: 'Change...
2
by: CptDondo | last post by:
I'm trying to write what should be a simple program, and it keeps hanging if I use volatile.... The program, stripped of its error checking, is this: unsigned short * start; unsigned short *...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.