Search

Meta

3.3 — Increment/decrement operators, and side effects

Incrementing (adding 1 to) and decrementing (subtracting 1 from) a variable are so common that they have their own operators in C. There are actually two version of each operator -- a prefix version and a postfix version.

Operator Symbol Form Operation
Prefix increment (pre-increment) ++ ++x Increment x, then evaluate x
Prefix decrement (pre-decrement) –– ––x Decrement x, then evaluate x
Postfix increment (post-increment) ++ x++ Evaluate x, then increment x
Postfix decrement (pre-decrement) –– x–– Evaluate x, then decrement x

The prefix increment/decrement operators are very straightforward. The value of x is incremented or decremented, and then x is evaluated. For example:

The postfix increment/decrement operators are a little more tricky. The compiler makes a temporary copy of x, increments x, and then evaluates the temporary copy of x.

In the second line of the above example, x is incremented from 5 to 6, but y is assigned the value of the copy of x, which still has the original value of 5.

Here is another example showing the difference between the prefix and postfix versions:

This produces the output:

5 5
6 4
6 4
6 4
7 3

On the third line, x and y are incremented/decremented before they are evaluated, so their new values are printed by cout. On the fifth line, a temporary copy of the original values (x=6, y=4) is sent to cout, and then the original x and y are incremented. That is why the changes from the postfix operators don’t show up until the next line.

Side effects

A side effect is a result of an operator, expression, statement, or function that persists even after the operator, expression, statement, or function has finished being evaluated.

Side effects can be useful:

The assignment operator has the side effect of changing the value of x permanently. Even after the statement has finished executing, x will have the value 5.

Side effects can also be dangerous:

C++ does not define the order in which function parameters are evaluated. If the left parameter is evaluated first, this becomes a call to add(5, 6), which equals 11. If the right parameter is evaluated first, this becomes a call to add(6, 6), which equals 12! Note that this is only a problem because one of the parameters to x has a side effect.

There are other cases where C++ does not specify the order in which certain things are evaluated, so different compilers will make different assumptions. Even when C++ does make it clear how things should be evaluated, some compilers implement behaviors involving variables with side-effects incorrectly. These problems can generally all be avoided by ensuring that any any variable that has a side-effect applied is used no more than once in a given statement.

Rule: Don’t use a variable that has a side effect applied to it more than once in a given statement.
Rule: Favor pre-increment and pre-decrement over post-increment and post-decrement. The prefix versions are not only more performant, you’re less likely to run into strange issues with them.

3.4 -- Sizeof, comma, and conditional operators
Index
3.2 -- Arithmetic operators

26 comments to 3.3 — Increment/decrement operators, and side effects

  • som shekhar

    you have written the statement for the post fix increment as;

    The postfix increment/decrement operators are a little more tricky.
    The compiler makes a temporary copy of x, increments x,
    and then evaluates the temporary copy of x.

    but compiler should first evaluate the temporary copy of x and then it should increment x.
    please correct me if i am wrong!!

    thanks
    Som Shekhar

  • kULDEEP

    CAN YOU EXPLAIN THE BELOW ASSIGMENT OPERATOR, PLEASE:

    INT SUM, CTR;
    SUM=12;
    CTR=4;
    SUM = SUM + (++CTR)

    THE VALUE IS 15 …..HOW?

    SUM = SUM + (-CTR)

    THE VALUE IS 15 …..HOW?

    SUM = SUM + (CTR++)
    THE VALUE IS 16 …..HOW?

    SUM = SUM + (CTR-)
    THE VALUE IS 16 …..HOW?

    thanx in advance

    • Peter P

      Tried to evaluate the first expression and I get the expected result SUM = 17.

      Have not tried the other exampels but assume I will get the expected results as well. No idea how you end up with your results?!

    • csvan

      At face value this looks strange…I will go over them in order.

      1. This one should evaluate to 17, like Peter P said. There is no way it can evaluate to 15, since it will become: (SUM = 12 + 5).

      2. again, something is wrong. This one should be (I think), SUM = 12 + (-4) = 8.

      3. This one should be correct, as the postfix ++ will increment CTR AFTER the expression is evaluated (I think).

      4. I have never seen a single - postfixed like this, I dont believe it should even compile.

      Use your compiler to try and compile each statement, and see what happens. I have just written my observations here, I did not compile the code.

  • Danny

    It says above that… “C++ does not define the order in which function parameters are evaluated.”
    But in the section “Precedence and associativity” it shows that () “Parenthesis”, () “Function calls”, () “Implicit assignments”, and , “comma” have an associative of left to right… what is the difference?

    • Dogbiscuit

      No, what he said is that function parameters could be done left to right, or right to left. E.g.

      It’s not defined whether you do a + b or b + a (makes no difference in this case, but with increment/decrement operators it could get messy.

    • Alex

      I can see how this would be confusing. The comma used inside a function call parameter list to separate the parameters isn’t the comma operator. So while the comma operator does have a left to right association, the order that parameters inside a function call are processed could be either direction.

  • moncef

    hi Alex!

    I tried to test the precedence of the ++ operator, both prefix and postfix.
    The code i typed in is:

    Why the is ++x++ illicit?
    Thanks for the nice tutorial.

    • Alex

      ++x++ evaluates as ++(x++) due to post-increment having a higher precedence than pre-increment.

      Note that both versions of ++ need to operate on an lvalue (a variable that has an address). With pre-increment, because the increment is done before the value is evaluated, the value is returned as an lvalue. However, with post-increment, the value gets evaluated before the increment, so the value is returned as an rvalue.

      So in your expression, x++ is returning an rvalue, and pre-increment can’t work with an rvalue, so the compiler throws an error.

      Note that if you write the expression as (++x)++, then it does work, because (++x) returns an lvalue that can be operated on by post-increment.

  • oh no . complecated. need to learn easiest way.

  • smitha

    Hi, I teach C++ to 12th graders. I encountered this problem in the lab wherein the statement

    I would expect the value 13, but my students got 14 as the output. any pointers?
    what is funny is that the following code gives the value 13.

    The only difference being in the way x is initialized. I am baffled!!!

    • pravin

      answer to the second code snippet is also = 14

    • X000X

      Remember that operator precedence requires that ++ be evaluated before + and =. So what happens is ++y is evaluated twice with y becoming 6 then 7. The addition 7+7 is then performed before finally assigning result 14 to x.

    • Kush

      I fear I also got two different answers, using Turbo c IDE.

      Now, the answer might lie in Order of precedence, though i cannot satisfactorily expalin it.

      Here, acc to table Alex gave:

      Pre-increment and Dynamic initialization fell in third box, with evalauation going Right to left.
      Therefore in second scenario, the case might be:
      (Going Left to Right)

      int x ( This evaluates third, giving x=13) = ++y(This evalautes second, giving y=7) + ++y (This evaluates first, giving y=6);

      IN first case, no dyanmic initialization, and hence, x is evaluated pretty much same way.
      x = ++y + ++y;
      Both ++y having higher precedence, than any other operand in statement are evaluated to 7 apeice, giving answer 14.

      Though, I think this can explain it, I would like to have confirmation…. I will post it out on forums sometime… and see if anyone agrees with me, or provides better explanation.

    • technocrat

      Hello buddy, dont panic, your students r right ,try to understand this-
      int y=5,x;
      x=(++y)+(++y);// x=6+7=13 but when compiler encounter 1st expresion ++y it increment value of y to 6 now y is 6 nd when it encounter another ++y in statement ++y, value of y becomes 7 now notice that compiler now have or assign value of y to 7, now compiler treats all occurence of y value to 7 in statement before assining value to x,so whether it is
      x=(++y)+(++y);
      x=6+7;//incremented or say highest value of y becomes value of y for compiler before assigning to x nd therefore expression becomes
      x=7+7;
      x=14;
      or consider another ex. for better understanding
      x=(++y)+(++y)+(++y);
      x=6+7+8;//incremented or highest value of y will become value of y before assining to x so it becomes-
      x=8+8+8;
      x=32; hope that u can understand now,thanks.

    • It’s as technorat said.
      consider this expression: x = (a++) + (a++);
      now what happens is it takes the value of a, adds the value of a to it, and then does the incrementing (if a = 5, then x will be 10, and a will be 7 in the end).
      It’s the same thing when having ++ in front.
      example x = (++a) + (++a);
      It takes a value, increments it, then it sees another ++ in the statement, so it increments ‘a’ again, and then it does the adding, meaning that if a was 5, then x will be 14, and a will be 7 in the end.
      Also - you don’t really need the brackets in this case, as ++ has higher priority than the standard + sign (tho it helps the readability).

  • nagaraj

    Hi all
    int i=2;
    i=++i * i++ * i++; answer i am geeting is 29
    n=++i+i++*i++; answer i am getting is 27
    printf(“%d”,++i+i++*i++); answer i am getting is 36

    how complier is going evalute? please reply me…

  • nagaraj

    Hi all
    int i=2;
    i=++i * i++ * i++; answer i am geeting is 29
    n=++i*i++*i++; answer i am getting is 27
    printf(“%d”,++i*i++*i++); answer i am getting is 36
    for same expression getting different values..please sort this problem

    how complier is going evalute? please reply me…

    • printf for some reason seems to evaluate the i++ once it’s done, so it’s 3 (you incremented it before using it - ++i) * 3 * 4.
      the second case (n=) simply evaluates the i++, and since the other additions are done only after the statement is done, you get 3*3*3
      the first case is the same as the second one, except it adds +2 gained from the increments (i++) before.

  • INNOVISION

    int t;
    t= ++t + ++t + t++ + t++;
    printf(“%d”,t);
    //result=14 how??

  • Ramadharkumar

    hey, this code give the output 14.
    int t=1;
    t=++t + ++t + t++ + t++;
    that is
    t=2+3 and in postincrement operator 3+4;
    t=2+3 + 3+4;
    t=3+3 + 4+4;
    t=6 +8;
    t=14;
    if the number of preincrement is greater than post then value of post operator is bigest value of preincrement operator;
    for example:
    t=1;
    t=++t + ++t + ++t + t++ + t++;
    output is 20; BECAUSE
    t=2+3+4 + 4+4;
    t=4+4+4 + 4+4;
    t=20;

    • ahleyn

      it’s really confusing.how come t=3+3+4+4?

      • Paperweight

        Given
        int t = 1;
        Since
        cout << ++t + ++t + t++ + t++;
        outputs 12 (as in 3 + 3 + 3 + 3), but
        t = ++t + ++t + t++ + t++;
        cout << t;

        outputs 14, I think what happens is:
        1. t is declared to be 1.
        1. t is preincremented. t is now 2.
        2. t is preincremented. t is now 3.
        3. t = t + t + t + t is evaluated. from 3 + 3 + 3 + 3, t is now 12.
        4. t is postincremented. t is now 13.
        5. t is postincremented. t is now 14.
        6. t is printed.

        • Paperweight

          Actually I’m probably wrong.

          //But wait! There's more!

          int t = 1;
          cout << t++ + t++ + t++ + t++ << endl;
          cout << t << endl << endl;
          // Should evaluate 1 + 1 + 1 + 1 as 4,
          // then output 4,
          // then increment t four times to 5,
          // then output t as 5.
          // Actually outputs 4 and 5 OK.

          t = 1;
          t = t++ + t++ + t++ + t++;
          cout << t << endl << endl;
          // Should evaluate 1 + 1 + 1 + 1 as 4,
          // then set t to 4,
          // then increment t four times to 8,
          // then output t as 8.
          // Actually outputs 8 OK.

          t = 1;
          cout << ++t + ++t + ++t + ++t << endl;
          cout << t << endl << endl;
          // Should increment t four times to 5,
          // then evaluate 5 + 5 + 5 + 5 as 20,
          // then output 20,
          // then output t as 5.
          // Actually outputs 15 and 5 WTF?

          t = 1;
          t = ++t + ++t + ++t + ++t;
          cout << t << endl;
          // Should increment t four times to 5,
          // then evaluate 5 + 5 + 5 + 5 as 20,
          // then set t to 20,
          // then output t as 20.
          // Actually outputs 15 WTF?

          • Alex

            Seems like your compiler may not be doing something quite correctly.

            Should evaluate as 20 and 5, and it does in Visual Studio 2008.

            That’s one of the many problems with including multiple expressions with side effects in a single statement. Even if the C++ language guarantees that it will evaluate a certain way (and it may not), your compiler may not do it correctly.

Leave a Comment

  

  

  

5 + 8 =

Put C++ code inside [code][/code] tags to use the syntax highlighter