aleksa said:
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