473,405 Members | 2,185 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,405 software developers and data experts.

Proper Use of Volatile?

Can someone help me out here? This is one of those areas of C
that I am fuzzy on. I'm not quite sure when I should use volatile.

If you could provide an example, that would help out a lot.

I know it has to do with the expectation that the variable can be
changed outside of the control of the program. I know it has to
do with telling the compiler to not optimize that piece of code,
so that the variable can be changed from outside of the program.

But I struggle with the thought process as to deciding when to
use it.

<OT>
I was reading the source code for ftp (the client), and I
see it used throughout. And I found myself second guessing
my understanding of its use.
</OT>

Thanks!

Sep 1 '06 #1
6 2310
bw*****@yahoo.com wrote:
Can someone help me out here? This is one of those areas of C
that I am fuzzy on. I'm not quite sure when I should use volatile.

If you could provide an example, that would help out a lot.

I know it has to do with the expectation that the variable can be
changed outside of the control of the program. I know it has to
do with telling the compiler to not optimize that piece of code,
so that the variable can be changed from outside of the program.
Specifically, it tells the compiler that the very act of
accessing the volatile variable, for read or for write, may have
a necessary side-effect. The compiled code must actually perform
all the accesses implied by the abstract machine, and cannot
optimize them away or rearrange them w.r.t. sequence points.
A loop that polls a volatile device register until the READY bit
is set must actually read the register on each iteration; the
compiler cannot just fetch it once and then go into a tight loop
testing and re-testing the fetched value. A sequence of
assignments like

*device_register = DEVICE_RESET;
*device_register = DEVICE_SETMODE | 42;
*device_register = DEVICE_START;

cannot be replaced by the final assignment alone.

Unfortunately, there remains one gigantic non-portable hole in
the semantics of volatile: The compiled code must perform all the
accesses implied by the abstract machine, but the implementation
gets to define what an "access" is. Many uses of volatile thus
require intimacy with the implementation's documentation.
But I struggle with the thought process as to deciding when to
use it.
A strictly-conforming C program needs volatile in only one
circumstance (unless I've forgotten something ;-): when a function
that calls setjmp() wants to rely on the value of a local variable
that might be changed between setjmp() and longjmp(). Makeing such
a variable volatile "forces it to memory" whenever it's changed, and
forces it to be read from memory whenever it's inspected. Thus you
never get a value in a register becoming out-of-date with respect
to the value in memory when longjmp() messes up the normal flow
of control.

Other uses of volatile are connected with implementation-
specific goodies like asynchronous signals, memory locations that
do something other than passively store values (e.g., hardware
counters, I/O status and command registers), and other sorts of
"independent activity." (Not including multi-threaded programs,
by the way: volatile is neither necessary nor sufficient for data
that's shared between threads.)

If you're not using setjmp()/longjmp() and you're not using
asynchronous signals and special memory locations and the like,
you don't need (or want) volatile.
<OT>
I was reading the source code for ftp (the client), and I
see it used throughout. And I found myself second guessing
my understanding of its use.
</OT>
Keep in mind that the author of the code may have been as
uncertain about volatile as you are. Just because something has
been ritten doesn't mene its rite.

--
Eric Sosman
es*****@acm-dot-org.invalid
Sep 1 '06 #2
bw*****@yahoo.com wrote:
Can someone help me out here? This is one of those areas of C
that I am fuzzy on. I'm not quite sure when I should use volatile.

If you could provide an example, that would help out a lot.
Volatile is often used when a variable is written in an interrupt
routine and read by a background routine. Or it may be written by one
thread of execution and read by another. Another use is for
memory-mapped I/O ports, instead of memory, such that reading at a
particular address queries the current state of hardware and writing to
the address may send control signals to external hardware.

All of these examples violate the normal execution model in which a
value, once written, does not change until explicitly written again by
the normal program control.

Multiple threads and interrupts are outside the scope of Standard C, but
are commonly used with C. Volatile improves the utility of C in these
non-strictly-conforming usages.

--
Thad
Sep 1 '06 #3
"bw*****@yahoo.com" wrote:
>
Can someone help me out here? This is one of those areas of C
that I am fuzzy on. I'm not quite sure when I should use volatile.

If you could provide an example, that would help out a lot.

I know it has to do with the expectation that the variable can be
changed outside of the control of the program. I know it has to
do with telling the compiler to not optimize that piece of code,
so that the variable can be changed from outside of the program.

But I struggle with the thought process as to deciding when to
use it.
NB: Both memory-mapped I/O and threads are beyond the scope of
clc, and the following examples which use busy-loops aren't
necessarily good coding practice, but I believe they show
some uses of volatile in an easy-to-understand method.

Consider memory-mapped I/O, such as a status register on an output
port:

extern char volatile StatusRegister;
#define STATUS_BUSY 0x01
extern char OutputPort;

void SendString(char *pt)
{
for ( ; *pt ; pt++ )
{
while ( StatusRegister & STATUS_BUSY )
;
OutputPort = *pt;
}
}

If StatusRegister weren't "volatile", then the compiler could
optimize the while loop to read it only once, and then either
exit the loop immediately, or turn it into an infinite loop.

Another situation is multiple threads. Following the example
above, you may have a loop that checks the status of the other
thread via a volatile variable. If the compiler can determine
that your loop cannot change the variable, then once again it
can be optimized to reading it only once, and your code will
never see the change.

Basically, "volatile" tells the compiler "don't assume that the
value of the variable hasn't changed, just because I haven't
changed it".
<OT>
I was reading the source code for ftp (the client), and I
see it used throughout. And I found myself second guessing
my understanding of its use.
</OT>
Well, as someone else pointed out, it may be that the person
who wrote the code you were examining didn't understand volatile,
either.

On the other hand, it's possible that the program you were
looking at use another thread to do the transfers, and the main
thread examines the volatile variable to get information about
the transfer.

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h|
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>

Sep 1 '06 #4
Eric Sosman wrote:
bw*****@yahoo.com wrote:
<snip>
>But I struggle with the thought process as to deciding when to
use it.

A strictly-conforming C program needs volatile in only one
circumstance (unless I've forgotten something ;-): when a function
that calls setjmp() wants to rely on the value of a local variable
that might be changed between setjmp() and longjmp(). Makeing such
<snip>

How about:
volatile sig_atomic_t flag;
So that a signal handler for one of the few signals that the C standard
defines can safely set or test the flag?
--
Flash Gordon
Sep 3 '06 #5
Flash Gordon wrote:
Eric Sosman wrote:
>bw*****@yahoo.com wrote:


<snip>
>>But I struggle with the thought process as to deciding when to
use it.


A strictly-conforming C program needs volatile in only one
circumstance (unless I've forgotten something ;-): when a function
that calls setjmp() wants to rely on the value of a local variable
that might be changed between setjmp() and longjmp(). Makeing such


<snip>

How about:
volatile sig_atomic_t flag;
So that a signal handler for one of the few signals that the C standard
defines can safely set or test the flag?
It's not necessary for synchronous signals, and as far as
I can tell asynchronous signals are outside the bounds of
strict conformance; that's why I mentioned them among the
"implementation-specific goodies."

--
Eric Sosman
es*****@acm-dot-org.invalid
Sep 3 '06 #6
Eric Sosman wrote:
Flash Gordon wrote:
>Eric Sosman wrote:
>>bw*****@yahoo.com wrote:

<snip>
>>>But I struggle with the thought process as to deciding when to
use it.

A strictly-conforming C program needs volatile in only one
circumstance (unless I've forgotten something ;-): when a function
that calls setjmp() wants to rely on the value of a local variable
that might be changed between setjmp() and longjmp(). Makeing such


<snip>

How about:
volatile sig_atomic_t flag;
So that a signal handler for one of the few signals that the C
standard defines can safely set or test the flag?

It's not necessary for synchronous signals, and as far as
I can tell asynchronous signals are outside the bounds of
strict conformance; that's why I mentioned them among the
"implementation-specific goodies."
I see no guarantee in the standard that any given signal will *not* be
raised by an asynchronous mechanism, such as the Unix kill command. So I
believe that this is strictly conforming (modulo trypographical errors):

#include <signal.h>
#include <stdio.h>

volatile sig_atomic_t flag;

void sig(int i)
{
flag = 1;
}

int main(void)
{
char buf[2];
signal(SIGINT,sig);
fgets(stdin, buf, sizeof buf);
return 0;
}

Since although flag can possibly be caused to be set in some
implementation defined defined manner no output actually depends on
whether this occurs or not. However, if you drop the volatile and some
implementation defined mechanism (e.g. the user pressing ctrl+C) is used
to cause a SIGINT to be raised then undefined behaviour is invoked
potentially affecting the output of the program, thus causing it to no
longer be strictly conforming.

Of course, I am stretching a bit here, but I would be interested from an
academic perspective in the opinions of others on this ;-)

The truth is I just never thought about volatile not being required if
the signal handler was only ever invoked through the use of the raise
function :-)
--
Flash Gordon
Being awkward just for the sake of being awkward.
Sep 3 '06 #7

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;
5
by: ben | last post by:
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...
14
by: Ian Pilcher | last post by:
It's pretty common to see declarations such as: static volatile sig_atomic_t caught_signal = 0; C99 defines sig_atomic_t as a "... (possibly volatile-qualified) integer type of an object that...
14
by: google-newsgroups | last post by:
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...
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...
94
by: Samuel R. Neff | last post by:
When is it appropriate to use "volatile" keyword? The docs simply state: " The volatile modifier is usually used for a field that is accessed by multiple threads without using the lock...
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 *...
3
by: Rakesh Kumar | last post by:
Hi - I am actually trying to get my feet in multi-threaded C++ programming. While I am aware that the C++ standard does not talk about threads (at least, for now - in C++03) - my question is more...
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: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
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
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
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.