There is no flaw with either machine; your statements are simply
provoking undefined behavior, according to the C++ and C languages.
Let's inspect the first of your output expressions, simplified to
bare bones:
cout << i << i++;
Via precedence and associativity, the equivalent expression is fully
parenthesized as:
( (cout << i) << (i++) );
Note this has the general form:
( (a) op (b) );
where each of a and b is itself an expression.
Now we are ready to consider the order in which such an expression is
evaluated. Clearly both the subexpressions a and b must be evaluated
before the op can be applied to them. However, for most binary op's,
it is explicitly not specified whether subexpression a is evaluated
before b, or whether subexpression b is evaluated before a.
Therefore, you evidently have one compiler that evaluates a before b,
while the other compiler evaluates your expression in the other order.
This is not a flaw in the language; the language very explictly says
that this order is not specified.
In both C and C++, only a few binary operators require left operand
evaluation before (or instead of) right operand evaluation, namely
, || &&
Also, the ternary ?: operator requires its leading operand to be
evaluated first.
Do keep in mind that precedence and associativity influence, but do
not in general uniquely determine, any order of evaluation (i.e., the
order in which operators are applied to their operands). When in
doubt, insert sequence points into your code.
The classic example of expressions to avoid is: A[i] = ++i; for a
vector A and an int i. Since assignment is an operator, it is undefined
whether the ++i is evaluated before or after the A[i].
I have been writing C code since 1974 or so, and C++ code since 1982 or
so; the rules I paraphrase above have not changed in all that time.
However, I have discovered over the years that precedence and
associativity rules are often misinterpreted as rules that dictate
(rather than merely influence) order of evaluation.
- WEB
Brian O'Reilly <irish@pizero.Colorado.EDU> wrote
on Wed May 26 12:34:03 1999:
| Does anyone know if there is an obvious solution to this:
|
| I have a simple program (yes I am a c++ beginner),
|
| #include <iostream.h>
|
| int main() {
| int i=4;
| cout << "i = " << i << ", i++ = " << i++ << endl;
| cout << "i = " << i << ", ++i = " << ++i << endl;
| return 0;
| }
|
|
| When I run it on an Alpha (or a Sun) I get output:
|
| i = 4, i++ = 4
| i = 5, ++i = 6
|
|
| when I run it on a LINUX box I get:
|
| i = 5, i++ = 4
| i = 6, ++i = 6
|
|
| In both instances I compile the code vis:
|
| g++ -o Test Test.cc
|
|
| So, is there some magic flag I need to use on LINUX?
<snip>