C++ Expression Evaluation Headaches

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 1Expr 2Expected jActual ji
++ii++664
i++++i664
i++i++544
++i++i784

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.

Related Books

Cocoa(R) Programming for Mac(R) OS X (3rd Edition) Exceptional C++ Style: 40 New Engineering Puzzles, Programming Problems, and Solutions (C++ In-Depth Series) Imperfect C++: Practical Solutions for Real-Life Programming C Programming Language (2nd Edition) (Prentice Hall Software) Programming Interviews Exposed: Secrets to Landing Your Next Job (Programmer to Programmer)

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.

Post a Comment




About

My name is Tim Fanelli, I am a software engineer in Northern NY. I spend most of my time working, and when I can, I try to post interesting things here.

Cigar Dossiers