Posted Sun, 25 Sep 2005
I recently posted a link to Bjorne Stroustrup's C++ FAQ, in which he points out that the value of:
int i = 2
int j = i++ + i++
is undefined. I decided to throw together a couple little sample problems to see just what it would do. My toy program looks like this:
#include <iostream>
using namespace std;
int main( int argc, char ** argv ) {
int i = 2;
int j = <expr1> + <expr2>;
cout << j << endl;
}
Where expr1 and expr2 are either i++ or ++i. So for instance, when I throw in
int j = i++ + i++
I would expect j to take on a value of 5 -- since i is initially 2, the first i++ would evaluate to 2 and assign a value of 3 to i. The second i++ then evaluates to 3 and assigns a value of 4 to i. The results were, as expected, not what I would expect. The following table summarizes the combination of i++'s and ++i's, what I would evaluate it to in my head, and what actually happened:
| Expr 1 | Expr 2 | Expected j | Actual j | i |
|---|---|---|---|---|
| ++i | i++ | 6 | 6 | 4 |
| i++ | ++i | 6 | 6 | 4 |
| i++ | i++ | 5 | 4 | 4 |
| ++i | ++i | 7 | 8 | 4 |
As you can see, when we mix ++i and i++, things seem to evaluate as expected, however i++ + i++ and
++i + ++i are incorrect. As B.S. points out in his FAQ, this behavior is due to the fact that the order
of evaluation of expressions is undefined. So when we do i++ + i++, there is no garuantee that expressions are evaluated
left to right, and there is no garuantee that the ++ operators will be evaluated before the addition operation (even
though, interestingly enough, ++ has a higher precendence than +)
Bjarne's answer to this nasty "problem"? Just don't do it. Expressions like this are confusing anyway, and simple enough to avoid.
add to del.icio.us




Comments
On June 22, 2008 at 07:07 PM Natasha26 wrote:
Hiya, do u know what the heck is going on there:
1) void(int*& i) { i++; } //? *& ?
2) int x;
int* p = &x;
int*&* pr = p; //? *&* ?
I was trying to apply the associativity rule, but it's really doing my head-in as to what is really going on. Thanks.
On June 22, 2008 at 07:07 PM Natasha26 wrote:
Hiya, do u know what the heck is going on there:
1) void(int*& i) { i++; } //? *& ?
2) int x;
int* p = &x;
int*&* pr = p; //? *&* ?
I was trying to apply the associativity rule, but it's really doing my head-in as to what is really going on. Thanks.
On June 22, 2008 at 07:07 PM Stefan Bialucha wrote:
Whether order of evaluation "is undefined" nor expressions "evaluate incorrect". ++ evaluates before +. ++ in front increments the value immediately; ++ at back let's use the value first and increments afterwards. So
j= ++i + ++i) is actual: ++i; ++i; j=i+i; => j=8
j= ++i + i++) is actual: ++i; j=i+i; i++; => j=6
j= i++ + ++i) is actual: ++i; j=i+i; i++; => j=6
j= i++ + i++) is actual: j=i+i; i++; i++; => j=4
It is the expectation derived from using paper and pencil - i.e. evaluate left to right (instead ++ before +) and incrementing both i separately (instead of incrementing the very same i) - that is incorrect.