Navigation



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 ++ ++x Increment x, then evaluate x
Prefix decrement –– ––x Decrement x, then evaluate x
Postfix increment ++ x++ Evaluate x, then increment x
Postfix 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:

int x = 5;
int y = ++x; // x is now equal to 6, and 6 is assigned to y

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.

int x = 5;
int y = x++; // x is now equal to 6, and 5 is assigned to y

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:

int x = 5, y = 5;
cout << x << " " << y << endl;
cout << ++x << " " << --y << endl; // prefix
cout << x << " " << y << endl;
cout << x++ << " " << y-- << endl; // postfix
cout << x << " " << y << endl;

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:

x = 5;

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:

int x = 5;
int nValue = Add(x, ++x);

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!

As a general rule, it is a good idea to avoid the use operators that cause side effects inside of compound expressions. This includes all assignment operators, plus the increment and decrement operators. Any operator that causes a side effect should be placed in it’s own statement.

Note that side effects are not confined to operators, expressions, and statements. Functions can also have side effects, which we will discuss in the section on global variables (and why they are evil).

3.4 — Sizeof, comma, and arithmetic if operators
Index
3.2 — Arithmetic operators

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

  • [...] 2007 Prev/Next Posts « 3.3 — Increment/decrement operators, and side effects | Home | News — Recent posts box split » Thursday, June 14th, 2007 at 7:41 [...]

  • [...] 2007 Prev/Next Posts « 3.1 — Precedence and associativity | Home | 3.3 — Increment/decrement operators, and side effects » Wednesday, June 13th, 2007 at 5:14 [...]

  • 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.

      add(a, b)

      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.

  • I don’t know where to put this question so I will just put it here.
    I wanted to create a function that would return the Oct number of a char value. So, considering the pattern of the Oct numbers in relation to the ASCII codes, I created the following code:

    int Oct()
    {
    	char OctC = 0;
    	int NOct = 0;
    	while (OctC != Data)
    	{
    		if ((NOct - 77) % (100) == 0)
    			NOct = NOct + 33;
    		else if ((NOct - 7) % (10) == 0)
    			NOct = NOct + 3;
    		else
    			++NOct;
    		++OctC;
    	}
    	return NOct;
    }
    

    The OctC value being the ASCII code of Data (which is a global variable), and NOct being the Oct number of Data, will this function return a proper result? Even if it does, is there a easier way or a shortcut to do this (such as a function in C++ that will do the job for you) because I’m only 13 and this took me a while to figure out.

  • I’m sorry, but the place I wrote

    NOct = NOct + 33;

    in the 8th line was actually meant to be

    NOct = NOct + 23;

    .

  • moncef

    hi Alex!

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

    #include <iostream>;
    int main()
    {
        using namespace std;
        int x = 1;
        int y = (++x++);
        cout << "x= "<<x<<endl;
        cout << "++x++= "<<y;
    }
    I have the following error:
    Line 7: non-lvalue increment.
    

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

  • 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

    int y = 5,x;
    x = (++y)+ (++y);
    cout<<x;
    

    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.

    int y=5;
    int x = (++y) + (++y);
    cout<<x;
    

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

    • pravin

      answer to the second code snippet is also = 14

    • 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.

      • saurabh verma

        boss actually whatever you have expalined i am getting that is for turbo c but still i am facing lots of problem pls sort it out
        i= – –i-i– – –i;
        i= ++i*++i*i++*++i;
        i=++i*++i*i++;
        i=i++*i++*++i*++i;
        i=i++*++i*++i;
        i=++i*++i*++i;
        plz sort this problem
        i am using gcc compiler…
        plz reply soon

    • 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).

  • 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.

  • Sachin

    Hi,
    I am a XII grade student. I happened to encounter the same problem
    as Smitha ma’m. I too got 14 for the first case and 13 for second case
    Moreover, I repeated trying for various combinations and i feel that
    all pre-increment operators are evaluated before evaluating the
    expression and all post-increment operators after evaluating the
    entire expression in the first case.
    In case of dynamic initialisation, I got the values incremented
    in between evaluation of the expression.
    int x= ++y + ++y
    evaluted as 6+7 =13
    but
    int x;
    x= ++y + ++y
    evaluated as 7+7=14
    Am I right? Pls tell me why this is so.
    Thanks in advance.

  • AP

    this also depends upon the compiuer. turbo c compiler will give answer 14 in both cases which is infact correct.

  • saurabh verma

    i am facing lots of problem pls sort it out
    i= – –i-i– – –i;
    i= ++i*++i*i++*++i;
    i=++i*++i*i++;
    i=i++*i++*++i*++i;
    i=i++*++i*++i;
    i=++i*++i*++i;
    plz sort this problem
    i am using gcc compiler…
    plz reply soon

  • quynhntn

    Fix me if i’m wrong n sorry about my bad english.
    Don’t apply increment\decrement twice to the same variable.
    it make somthing ambiguous in C++
    U can use a temp variable.
    Ex: i=i++*i++*++i*++i;
    int i = 1;
    int a = i++; ( a= 1, i = 2)
    a = a * (i++); ( a=2, i = 3)
    a = a * (++i); ( i =4, a = 2*4=8, )
    a = a * (++i); ( i = 5, a = 8*5=40 )

  • 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??

  • INNOVISION

    int t=1;
    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?

    • zaibi099

      for t=1 it is 12 not 14 in C++ ??? how !!

      Qustn :2 >>

      if a=5 then :
      cout<<a++ + –a; // gives answer = 8
      how. please xplain..thank yu

  • ahleyn

    #include
    using namespace std;
    int main()
    {
    int x=5, y=1;
    do{
    cout<0&&y<5);
    return 0;
    }

    -what is the output of this code? i'm having a really hard time. i need your help. pleaseeee? anyone?

  • [...] found one definition here, but doesn’t this make each and every statement of code a side [...]

  • Paperweight

    Anyway the gcc documentation of that error code is thus:

    -Wsequence-point
    Warn about code that may have undefined semantics because of violations of sequence point rules in the C and C++ standards.

    The C and C++ standards define the order in which expressions in a C/C++ program are evaluated in terms of sequence points, which represent a partial ordering between the execution of parts of the program: those executed before the sequence point, and those executed after it. These occur after the evaluation of a full expression (one which is not part of a larger expression), after the evaluation of the first operand of a &&, ||, ? : or , (comma) operator, before a function is called (but after the evaluation of its arguments and the expression denoting the called function), and in certain other places. Other than as expressed by the sequence point rules, the order of evaluation of subexpressions of an expression is not specified. All these rules describe only a partial order rather than a total order, since, for example, if two functions are called within one expression with no sequence point between them, the order in which the functions are called is not specified. However, the standards committee have ruled that function calls do not overlap.

    It is not specified when between sequence points modifications to the values of objects take effect. Programs whose behavior depends on this have undefined behavior; the C and C++ standards specify that “Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be read only to determine the value to be stored.”. If a program breaks these rules, the results on any particular implementation are entirely unpredictable.

    Examples of code with undefined behavior are a = a++;, a[n] = b[n++] and a[i++] = i;. Some more complicated cases are not diagnosed by this option, and it may give an occasional false positive result, but in general it has been found fairly effective at detecting this sort of problem in programs.

    The standard is worded confusingly, therefore there is some debate over the precise meaning of the sequence point rules in subtle cases. Links to discussions of the problem, including proposed formal definitions, may be found on the GCC readings page, at http://gcc.gnu.org/readings.html.

    This warning is enabled by -Wall for C and C++.

    That explains it…

You must be logged in to post a comment.