Advertisement

Prefix and Postfix Increment Operator Question

Started by June 01, 2001 10:40 PM
8 comments, last by Fredric 23 years, 8 months ago
Allllrighty. I''ve been programming for a solid year and a half now, and I''ve never really came across the prefix Operator (eg: ++me). I''ve always used the postfix (me++) in order to increment a value, but I just got my hands on someone else''s code, and they''ve used the prefix operator, which I''m totally confused about. I really don''t see the difference in: int a = 0; a++; ++a; What is the difference? Where and why would the prefix operator be used instead of the postfix? Postfix just seems so...natural.
3D Math- The type of mathematics that'll put hair on your chest!
Hey, prefix operator is so that you can increment the value before you use it.

int a = 0;
int b = 0;

if (a++ == 1) // here a is still zero so the condition fails
{ // then a = a + 1
//Boink if a = 1 //
}

// now a is 1


if(++b == 1) //first b = b+ 1 then check so here b = 1
{
//Boink if b = 1
}

// b still 1



hope that clears it up.
We are here just like this,It really doesn't matter why.The world is here like it is,'We could laugh we could cry.Is it good or is it bad,Wright or maybe wrong?There's no use of being sad,Without a purpose within a song.
Advertisement
The prefix operator, or, more correctly, the preincrement operator, increased the variable's value by one prior to the evaluation of the statement fragment. However, it is also right-to-left associative, which has interesting consequences when you use pre- and postincrementation along with addition (or subtraction). For example:

int a = 1;
int b = ++a + ++a + ++a;
// b will be 10; compile it and verify

It has to do with the way the statement is fragmented. The second statement is actually 6 statements in one (3 incrementations, 2 additions and one assignment), as follows:

int b = ++a + ++a + ++a;
// addition (+) has left to right (normal) associativity, so
=> int b = (++a) + (++a + ++a); // two statements
=> int b = (c) + (++c + ++c); // incrementation of a before addition yields c = 2
// second half of addition (++c + ++c) will increment c twice before adding, giving d = 4;
=> int b = c + d + d;
// = 2 + 4 + 4;
// = 10;

Pre- or postincrementation can make or break an iterative algorithm, so a good understanding of them is necessary. For the record, I was also educated on these very forums (what goes around...) on the importance of associativity and operator precedence. The key is knowing what your compiler will do with a piece of code - the secret to writing efficient C or C++ (especially C).

Good luck

Edited by - Oluseyi on June 1, 2001 11:59:51 PM
The prefix operator performs the inc/decrement operation before the condition after it (if there is one), and the postfix operator performs the operation after the condition after it. For instance:

while(--myInt>0) that would decrement myInt before the test to see if it is above 0 or not, so you are looking at one less time going through the loop than you may expect.

while(myInt-->0) this would decremnt myInt after the test, so you are looking at going through the loop every time you would expect it to.

------------------------------
Trent (ShiningKnight)
NovaStorm Games
Project: OpenGL baby. None of that new-fangled Die-rect Three Dee
heh, thanks a lot you guys! I understand the huge difference now. Wowza... the prefix would have been a lot easier to use than the postfix in some of my programs. Thanks a lot!

And, correct me if I''m wrong, but wouldn''t:

a = 1;
b = ++a + ++a + ++a;

b now equals 9? Cuz you have b = (1+1 = 2) + (2+1 = 3) + (3+1=4) = 2+3+4 = 9?

3D Math- The type of mathematics that'll put hair on your chest!
I believe the above question is undefined in C++, and is a matter of compiler design; there was a very similar thread here just recently that delved into this.

Regardless, something missing from this discussion is that some classes have overloaded the preincrement and posincrement operators. It''s possible that the postincrement (me++) is less efficient than the preincrement (++me). An example class is the standard iterator from STL: postincrement requires the iterator to create a copy of itself, increment itself and then return the copy. Preincrement just requires an increment.

So, in my code (where possible) I''ve gotten in the habit of using preincrement. There are algorithms where it doesn''t fit, but if it''s alone on a line or the terminating condition on a for or while, I always use preincrement.
Advertisement
I''d like to point out that Stoffel indeed touches upon the most important reason to use the preincrement operator: STL iterators. Using the preincrement operator on an iterator doesn''t generate a temporary object of the iterator before it''s increased. Much more efficient if you do a loop which increments the iterator!
quote:
Original post by Fredric
And, correct me if I''m wrong, but wouldn''t:

a = 1;
b = ++a + ++a + ++a;

b now equals 9? Cuz you have b = (1+1 = 2) + (2+1 = 3) + (3+1=4) = 2+3+4 = 9?


Note that the statement is a number of statements rolled up into one. Assembly only performs one operation at a time, which is exactly what machine language (and thus the processor) does, ignoring dual-pipelining. Therefore,

b = (1+1 = 2) + {(2+1 = 3) + (3+1 = 4) } if evaluated linearly from left to right. However, preincrement is right-to-left, and has higher precedence than addition (so all preincrements are evaluated before addition within a statement fragment. Note that; within a fragment (how the compiler would see it), not an entire statement as you would write it.

The porion within brackets would evaluate as
c = (2+1) = 3 // first preincrement
c = (3+1) = 4 // second preincrement
d = c + c = 8
And then b = 2 + d = 2 + 8 = 10.

But don''t take my word for it; compile it and observe. I made a similar mistake, thinking that all preincrements would be evaulated before all additions, resulting in 12. Getting 10 was quite a shock!
And to complement Stoffel and JungleJim''s excellent pointers, the same effect can be obtained with a preincrement operation if the preincrement is performed in a statement following the use of the value.

ie, b = a++;

is equivalent to

b = a;
++a;

and intrinsically no less efficient, even with integers, though clockcycle issues could potentially cause minor lags in superscalar processors.
I always cringe whenever people start talking about precedence and order-of-operations near pre/post increment/decrement operators. Any of my reports who wrote something even vaguely like

int b = ++a + ++a + ++a;

would be told to rewrite it so that mere mortals could understand it and the next version of the compiler that gets used doesn''t introduce impossible to find bugs because of errors in the programmer''s understanding of how this should be evaluated, bugs in the compiler, ommisions in the language spec, etc., etc.

IMHO these operators should be avoided except in the most trivial of usages. They''re far more likely to cause bugs then they are to noticably improve performance.

-Mike
-Mike

This topic is closed to new replies.

Advertisement