DaKoadMunky wrote:
<CODE>
#include <iostream>
using namespace std;
int Foo(int x,int y)
{
int result = x;
result*=y;
result+=y;
return result;
}
int main()
{
cout<<Foo(2,4)<<endl; // I expect this to output 12 --LINE 1
cout<<Foo(4,2)<<endl; //I expect this to output 10 --LINE 2
return 0;
}
</CODE>
Are my expectations concerning the output of this program reasonable?
My concern stems from a lack of understanding of instruction reordering as it
relates to observable behavior.
Specifically I wonder if the expressions result*=y and result+=y in function
Foo could be swapped. That of course would change the meaning of Foo.
However, the following quote from the Draft Ansi C++ Standard makes me think
that the meaning of Foo is not observable behavior...
"The observable behavior of the abstract machine is its sequence of reads and
writes to volatile data and calls to library I/O functions."
Based on this quote the only behavior I would expect is that LINE 1 will
execute before LINE 2.
When a compiler reorders instructions that don't involve R/W to volatile data
and calls to library I/O functions how does it know that it is not changing the
meaning of a program?
Any insights as to what I am not grokking would be appreciated.
A translator is allowed to set the ordering of the instructions as long
as the functionality remains the same.
In your example, changing the order of the mathematical assignments
will change the meaning. However, there is nothing stopping a
translator changing the order of the assignment operation.
Your function evaluates the expression: f(x,y) = x * y + y;
The actually assignment of the value to result could be postponed
or not even occur at all (since the value is returned and not
stored in any static memory location). For example, your function
could be translated as:
int Foo(int x, int y)
{
return x * y + y;
}
The above function provides the same functionality, but has
no assignment operations.
There are no libraries calls, no I/O and no volatile or static
variables.
However, changing the order of the operations will change the
functionality.
The rules allow for compilers to optimize code. The qualifiers
"static", "volatile" and "mutable" are used to control the
optimization. During debugging, I may declare a variable
in a function as "static" so that the variable isn't "optimized
away". I use "volatile" when accessing hardware values so that
the compiler doesn't "optimize away" a variable that is read
only once.
--
Thomas Matthews
C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq:
http://www.parashift.com/c++-faq-lite
C Faq:
http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.comeaucomputing.com/learn/faq/
Other sites:
http://www.josuttis.com -- C++ STL Library book