if you really want that single instruction as a function by itself and
you want it to write directly in the global variable, then you should
at least declare it naked.
Perhaps this is a case where we have misunderstood each other - as far as I
can tell, you said that Grant's code should be split with an extra function,
and I disagreed. Did I misunderstand you?
if this was the source:
------------VERSION 1 ------------------
#include ....
unsigned int two;
void foo(){
two = P6IN + P6IN;
}
void main(){
....
foo();
....
..make something with "two"...
}
---------------------------
I would have rather rewritten it as:
-----------------VERSION 2--------
#include ....
unsigned int two;
unsigned int foo(){
unsigned int tmp;
tmp = P6IN;
tmp += P6IN;
return tmp;
}
void main(){
....
two = foo();
....
..make something with "two"...
}
-----------------------------
and I would especially avoid writing IOCCC style code like:
unsigned int foo(){
unsigned int tmp = P6IN;
return tmp + P6IN;
}
which is exactly the same, but it's the highway to coffe and GDB.
I came across a similar problem writing for another processor architecture
(er OK I admit it a PIC). The line
P2 = a+b+c;
In this case, either P2 was declared incorrectly (i.e., it was not declared
as a volatile), or the compiler generated incorrect code.
In general, yes, the compiler is free to use "two" to store half the
calculation. In practice, of course, it will not - as you say, it will use
a register (on the PIC, it makes sense to use the global as a temporary
storage, since it has no real registers). But the only way to make
absolutely sure that "two" is not written in two steps is to make "two" a
volatile as well.
Apart from the fact that my limited knowledge of volatiles prevents me
to understand how it is possible to ensure that two is not written in
two steps, John highlighted the most important reason for which you
should write that foo function the way I think.
If you get an interrupt in the middle of the two readings of version
1, you'll find yourself with an inconsistent value of "two".....and
Murphy assures you that the service routine will be using "two" for
some critical stuff.
In this case, you should declare version 1 of foo() as "critical",
with all the pros and cons of that kind of functions.
With version 2 of foo(), there's never an inconsitency...in the worst
case you'll have an old value of "two" (not updated yet), but this is
a far more predictable behaviour to handle.
R.