Substitute for volatile

V

vijay.rajamanickam

I am a newbie w.r.t. compiler optimizations and I believe these
optimizations are generally done in function level. Can I safely assume
that
if I use getter & setter functions, I can effectively substitute using
the
qualifier volatile for variables in all instances. Thanks in advance


R
V
 
L

Lew Pitcher

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

I am a newbie w.r.t. compiler optimizations and I believe these
optimizations

/which/ optimizations?
are generally done in function level.
Can I safely assume that if I use getter & setter functions,
I can effectively substitute using the qualifier volatile
for variables in all instances. Thanks in advance

I'm not certain of what you are asking here.

Perhaps I can answer you this way:

"volatile" is a hint to the compiler that the contents of a variable may
change out-of-band, and that it should not make assumptions about the
variable's contents in it's optimizations. It doesn't matter whether the
optimizations are at a function level, or at some other level;
"volatile" says don't make them.

The basic assumption that "volatile" disables is the one that the
compiler can keep track of variable initializations and discard
unnecessary initializations silently. This sort of behaviour occurs when
the variable is set with a value, and the value isn't seen to change
before the next reference to the variable. In a case like that, the
compiler is permitted to discard related operations so long as the
appearance of continuity is preserved.

For instance, given the code fragment...

{
int a = 10; /* A */
a = 10; /* B */
if (a == 10) return; /* C */
}

Since variable "a" is initialized to 10 at line "A", and no intervening
changes are made to the value of "a" between line "A" and line "B", the
compiler may assume that variable "a" has a value of 10 at line "B". It
may then discard the initialization of line "B" completely, because the
end condition of line "B" (a having the value of 10) is already guaranteed.

Similarly, since "a" is still guaranteed to have the value of 10 at line
"C", the compiler may optimize away the test (a == 10) and substitute a
TRUE value for it, and may even further optimize away the entire if
statement (because it is always TRUE) and just generate the code for the
return statement.

With volatile,

{
volatile int a = 10; /* A */
a = 10; /* B */
if (a == 10) return; /* C */
}

the compiler is forbidden to optimize away either line B or line C

Please note that "volatile" is not the default behaviour; if you don't
need "volatile", you don't have to use it.

So, when would you need "volatile"? You'd need it when the variable may
change asynchronously to the flow of the program. Typically, this comes
from the activities of a signal handler, which can run asynchronously to
the main code. There are also per-platform cases where volatile may be
necessary, but these are not explicitly covered by ISO C.


HTH

PS, your reference to "getter" and "setter" functions leads me to
question whether you are programming in C (the topic of comp.lang.c) or
C++. If you have a C++ mindset, then I must warn you that C is a
different language than C++, and while you can write OO code in C, most
do not.


- --

Lew Pitcher, IT Specialist, Enterprise Data Systems
Enterprise Technology Solutions, TD Bank Financial Group

(Opinions expressed here are my own, not my employer's)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (MingW32)

iD8DBQFDw7cXagVFX4UWr64RAu/MAKDGoKmH9Drn4YhONvGZx/Juovu9ogCguRo8
OxWGBQn+BGeLrJpYAgRc2Wk=
=lhdH
-----END PGP SIGNATURE-----
 
V

vijay.rajamanickam

Thanks Lew for your detailed explanation. I am pretty aware of the use
of volatile & I use C. Now that I read it again, I think I should have
worded my question differently..

Let me take the example that you had quoted for instance (with one
change - "a" being a global variable).

volatile int a;
{

a = 10; /* A */
a = 10; /* B */
if (a == 10) return; /* C */

}

Will the following code be considered equivalent to your code?

int a;
int GetA ()
{
return a;
}

void SetA (int x)
{
a = x;
}

{
a = 10; /* A */
SetA(10); /*B*/
if (GetA() == 10) return; /* C */
}

I think, in this case we can get away with the risk of compiler
skipping lines "B" & "C". This was my doubt.
 
K

Keith Thompson

Thanks Lew for your detailed explanation. I am pretty aware of the use
of volatile & I use C. Now that I read it again, I think I should have
worded my question differently..

Let me take the example that you had quoted for instance (with one
change - "a" being a global variable).

volatile int a;
{

a = 10; /* A */
a = 10; /* B */
if (a == 10) return; /* C */

}

Will the following code be considered equivalent to your code?

int a;
int GetA ()
{
return a;
}

void SetA (int x)
{
a = x;
}

{
a = 10; /* A */
SetA(10); /*B*/
if (GetA() == 10) return; /* C */
}

I think, in this case we can get away with the risk of compiler
skipping lines "B" & "C". This was my doubt.

No, it's not equivalent. The compiler is as free to do optimizations
across functions as it is within functions; it could still
legitimately delete the SetA(10) call and replace the
"if (GetA() == 10) return;" with just "return;".

If the GetA and SetA functions are in a separately compiled file, the
optimization becomes more difficult and less likely to be done; it
probably has to be done at link time.

It's probably less likely that a compiler will perform these
optimizations across functions, and even less likely that
optimizations will be done at link time, but there's no point in
assuming that they won't be done.

If you need volatile, use volatile. (And why are you trying to avoid
it in the first place?)
 
C

Chris Torek

Let me take the example that you had quoted for instance (with one
change - "a" being a global variable).

volatile int a;

[and some function f() whose contents are]
{

a = 10; /* A */
a = 10; /* B */
if (a == 10) return; /* C */ ...
}

Will the following code be considered equivalent to your code?

int a;
int GetA () { return a; }
void SetA (int x) { a = x; }
[and some function f() whose contents are]
{
a = 10; /* A */
SetA(10); /*B*/
if (GetA() == 10) return; /* C */ ...
}

I think, in this case we can get away with the risk of compiler
skipping lines "B" & "C". This was my doubt.

C compilers that will optimize out the calls to SetA() and GetA()
do in fact exist. They are not, perhaps, as common as compilers
that will not optimize out those calls -- but take a look at the
actual code for f() emitted by gcc (3.2.3):

/* a, GetA, and SetA defined as above, in the same file */
extern void oops(void);

void f(void) {
a = 10;
SetA(10);
if (GetA() != 10)
oops();
}
% cc -O4 -S -ansi -pedantic t.c
% cat t.s
... code for GetA and SetA omitted ...
f:
pushl %ebp
movl %esp, %ebp
movl $10, a
leave
ret

Note that function f() simply sets "a" to 10 and never tests it.

If you might ever use the GNU compilers, do not fail to use "volatile"
where needed.
 

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

Forum statistics

Threads
474,172
Messages
2,570,934
Members
47,478
Latest member
ReginaldVi

Latest Threads

Top