[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c

Should this static variable be volatile?

aleksa

5/16/2011 10:18:00 PM

sys_handler() calls user_handler() which may call
SetRetVal() to change the default RetValue:

**********************
static BOOL RetValue; // should this be volatile?

BOOL sys_handler (void)
{
RetValue = FALSE; // set default RetValue before
user_handler(); // calling user handler
return RetValue; // return RetValue (which may have changed)
}

void SetRetVal (BOOL newretval)
{
RetValue = newretval;
}
**********************

Should RetValue be volatile?

TIA


6 Answers

Keith Thompson

5/16/2011 11:02:00 PM

0

"aleksa" <aleksazr@gmail.com> writes:
> sys_handler() calls user_handler() which may call
> SetRetVal() to change the default RetValue:
>
> **********************
> static BOOL RetValue; // should this be volatile?
>
> BOOL sys_handler (void)
> {
> RetValue = FALSE; // set default RetValue before
> user_handler(); // calling user handler
> return RetValue; // return RetValue (which may have changed)
> }
>
> void SetRetVal (BOOL newretval)
> {
> RetValue = newretval;
> }
> **********************
>
> Should RetValue be volatile?

Given what you've shown us, there's no reason it should need to be. The
compiler can't assume that the call to user_handler() won't change the
value of RetValue, so it has to generate code to re-read it.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.ne...
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

jt

5/16/2011 11:19:00 PM

0

aleksa <aleksazr@gmail.com> wrote:
> sys_handler() calls user_handler() which may call
> SetRetVal() to change the default RetValue:

> **********************
> static BOOL RetValue; // should this be volatile?

> BOOL sys_handler (void)
> {
> RetValue = FALSE; // set default RetValue before
> user_handler(); // calling user handler
> return RetValue; // return RetValue (which may have changed)
> }

> void SetRetVal (BOOL newretval)
> {
> RetValue = newretval;
> }
> **********************

> Should RetValue be volatile?

No. The compiler must consider that 'RetVal' becomes changed
as a side-effect of calling user_handler() - it's completely
normal that a function called changes a global variable.

You need 'volatile' in three (as far as I am aware of at the
moment) situations. First, if the compiler can reasonably
assume that a setting or reading a variable has no effect on
the outcome of a computation, e.g. with

void delay( int x )
{
int i
for ( i = 0; i < x; i++ )
;
}

the compiler may "see" that changing 'i' has no effect at all
(neither for the outcome of the function nor by side-effects)
and thus it (rather likely) will remove the whole loop (or
even any calls of delay()). In this case qualifying 'i' as
'volatile' makes a big difference since it keeps the compiler
from making those assumptions, so it has to produce code that
runs the complete loop, resulting in some CPU time consumed,
which was the real intention of the loop.

The second one is when you deal with hardware registers,
mapped into the address space. Writing to or reading from
such a register can have side-effects the compiler can't
know about. So, for example, whe you have

void trigger_the_card( )
{
int *x = 0xdeadbeef; /* x now points to a memory-
mapped register of the card */
*x;
}

it will look to the compiler as if nothing reasonable is
happening here - the result of reading from address 'x'
is never used. But in reality this is not about the
value read but reading from the memory-mapped register
triggers some action but which the compiler doesn't (and
can't) know about. So using 'volatile' is required.

And, third, there are global variables that may be chan-
ged asynchronously, i.e. not within the normal program
flow, e.g. via an interrupt handler. Also in those cases
the compiler can't forsee this (it assumes that the pro-
gram it compiles will be runing uninterrupted until the
very end).

But none of this is what happens in the case you describe.
You have a global variable that can be changed from every
point in the program (or at least, since it's qualified as
static, from any place in the translation unit it's defined
in). Thus the compiler can't assume that it will have the
same value after a call of some function it had before that
call. Thus qualifying it as 'volatile' is not needed.

Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://t...

Angel

5/17/2011 2:18:00 PM

0

On 2011-05-16, aleksa <aleksazr@gmail.com> wrote:
> sys_handler() calls user_handler() which may call
> SetRetVal() to change the default RetValue:
>
> **********************
> static BOOL RetValue; // should this be volatile?
>
> BOOL sys_handler (void)
> {
> RetValue = FALSE; // set default RetValue before
> user_handler(); // calling user handler
> return RetValue; // return RetValue (which may have changed)
> }
>
> void SetRetVal (BOOL newretval)
> {
> RetValue = newretval;
> }
> **********************
>
> Should RetValue be volatile?

Judging by the code shown, I see no reason to. From what I understand,
volatile comes into play when something outside your algorithm can
change the state of a variable. For example, if a signal handler
changes it, or if it is mapped to a device I/O port or something like
that.


--
"C provides a programmer with more than enough rope to hang himself.
C++ provides a firing squad, blindfold and last cigarette."
- seen in comp.lang.c

Datesfat Chicks

5/17/2011 10:24:00 PM

0

On 16 May 2011 23:18:39 GMT, jt@toerring.de (Jens Thoms Toerring)
wrote:

>aleksa <aleksazr@gmail.com> wrote:
>> sys_handler() calls user_handler() which may call
>> SetRetVal() to change the default RetValue:
>
>> **********************
>> static BOOL RetValue; // should this be volatile?
>
>> BOOL sys_handler (void)
>> {
>> RetValue = FALSE; // set default RetValue before
>> user_handler(); // calling user handler
>> return RetValue; // return RetValue (which may have changed)
>> }
>
>> void SetRetVal (BOOL newretval)
>> {
>> RetValue = newretval;
>> }
>> **********************
>
>> Should RetValue be volatile?
>
>No. The compiler must consider that 'RetVal' becomes changed
>as a side-effect of calling user_handler() - it's completely
>normal that a function called changes a global variable.
>
>You need 'volatile' in three (as far as I am aware of at the
>moment) situations. First, if the compiler can reasonably
>assume that a setting or reading a variable has no effect on
>the outcome of a computation, e.g. with
>
>void delay( int x )
>{
> int i
> for ( i = 0; i < x; i++ )
> ;
>}
>
>the compiler may "see" that changing 'i' has no effect at all
>(neither for the outcome of the function nor by side-effects)
>and thus it (rather likely) will remove the whole loop (or
>even any calls of delay()). In this case qualifying 'i' as
>'volatile' makes a big difference since it keeps the compiler
>from making those assumptions, so it has to produce code that
>runs the complete loop, resulting in some CPU time consumed,
>which was the real intention of the loop.
>
>The second one is when you deal with hardware registers,
>mapped into the address space. Writing to or reading from
>such a register can have side-effects the compiler can't
>know about. So, for example, whe you have
>
>void trigger_the_card( )
>{
> int *x = 0xdeadbeef; /* x now points to a memory-
> mapped register of the card */
> *x;
>}
>
>it will look to the compiler as if nothing reasonable is
>happening here - the result of reading from address 'x'
>is never used. But in reality this is not about the
>value read but reading from the memory-mapped register
>triggers some action but which the compiler doesn't (and
>can't) know about. So using 'volatile' is required.

There is a second reason to declare hardware-mapped registers
volatile: the value may change without the code being compiled
changing it.

For example,

while (HW_REG & 0x1) ;

could, with some optimizations, generate a loop that simply can't
exit. HW_REG may be read once only in the optimized code.

>And, third, there are global variables that may be chan-
>ged asynchronously, i.e. not within the normal program
>flow, e.g. via an interrupt handler. Also in those cases
>the compiler can't forsee this (it assumes that the pro-
>gram it compiles will be runing uninterrupted until the
>very end).

Threads and memory shared between processes are variants of this ...
in effect, they are invoked "indirectly" as the result of an
interrupt.

>But none of this is what happens in the case you describe.
>You have a global variable that can be changed from every
>point in the program (or at least, since it's qualified as
>static, from any place in the translation unit it's defined
>in). Thus the compiler can't assume that it will have the
>same value after a call of some function it had before that
>call. Thus qualifying it as 'volatile' is not needed.

DFC

io_x

5/18/2011 5:31:00 PM

0


"Jens Thoms Toerring" <jt@toerring.de> ha scritto nel messaggio
news:93dpmfF91bU1@mid.uni-berlin.de...
> aleksa <aleksazr@gmail.com> wrote:
>> sys_handler() calls user_handler() which may call
>> SetRetVal() to change the default RetValue:
>
>> **********************
>> static BOOL RetValue; // should this be volatile?
>
>> BOOL sys_handler (void)
>> {
>> RetValue = FALSE; // set default RetValue before
>> user_handler(); // calling user handler
>> return RetValue; // return RetValue (which may have changed)
>> }
>
>> void SetRetVal (BOOL newretval)
>> {
>> RetValue = newretval;
>> }
>> **********************
>
>> Should RetValue be volatile?
>
> No. The compiler must consider that 'RetVal' becomes changed
> as a side-effect of calling user_handler() - it's completely
> normal that a function called changes a global variable.
>
> You need 'volatile' in three (as far as I am aware of at the
> moment) situations. First, if the compiler can reasonably
> assume that a setting or reading a variable has no effect on
> the outcome of a computation, e.g. with
>
> void delay( int x )
> {
> int i
> for ( i = 0; i < x; i++ )
> ;
> }
>
> the compiler may "see" that changing 'i' has no effect at all
> (neither for the outcome of the function nor by side-effects)
> and thus it (rather likely) will remove the whole loop (or
> even any calls of delay()). In this case qualifying 'i' as
> 'volatile' makes a big difference since it keeps the compiler
> from making those assumptions, so it has to produce code that
> runs the complete loop, resulting in some CPU time consumed,
> which was the real intention of the loop.

it has not effect so the compiler cut that code right?
wrong the programmer write that code, that code has been run
volatile or not volatile



Tim Rentsch

5/19/2011 8:52:00 AM

0

jt@toerring.de (Jens Thoms Toerring) writes:

> [snip]
>
> You need 'volatile' in three (as far as I am aware of at the
> moment) situations. [snip]

Two others: one related to accessing global variables
in a signal handler, the other related to setjmp/longjmp.