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 versions 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 (post-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 or decrements the original x (not the copy), and then evaluates the temporary copy of x. The temporary copy of x is then discarded.

Let’s examine how this last line works in more detail. First, the compiler makes a temporary copy of x that starts with the same value as x (5). Then it increments the original x from 5 to 6. Then the compiler evaluates the temporary copy, which evaluates to 5, and assigns that value to y. Then the temporary copy is discarded.

Consequently, y ends up with the value of 5, and x ends up with the value 6.

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.

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.

Side effects

A function or expression is said to have a side effect if it modifies some state (e.g. any stored information in memory), does input or output, or calls other functions that have side effects.

Most of the time, side effects are useful:

The assignment operator in the above example has the side effect of changing the value of x permanently. Even after the statement has finished executing, x will have the value 5. Operator++ has the side effect of incrementing x. The outputting of x has the side effect of modifying the console.

However, side effects can also lead to unexpected results:

C++ does not define the order in which function arguments are evaluated. If the left argument is evaluated first, this becomes a call to add(5, 6), which equals 11. If the right argument 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 argument to function add() has a side effect.

Here’s another popular example:

What value does this program print? The answer is: it’s undefined.

If the ++ is applied to x before the assignment, the answer will be 1 (postfix operator++ increments x from 1 to 2, but it evaluates to 1, so the expression becomes x = 1).

If the ++ is applied to x after the assignment, the answer will be 2 (this evaluates as x = x, then postfix operator++ is applied, incrementing x from 1 to 2).

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 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. If you do, the result may be undefined.

Please don’t ask why your programs that violate the above rule produce results that don’t seem to make sense. That’s what happens when you write programs that have “undefined behavior”. 🙂

For more information on undefined behaviors, revisit the “Undefined Behavior” section of lesson 1.3 -- A first look at variables, initialization, and assignment.

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

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

  • prince

    hi Alex
    these are two function used in stack implementation by many sites such as geeksforgeeks
    shouldn't they be used as they contain pre increment(side effects) and assignment operator in same given statement.
    void push(struct Stack* stack, int item)
    if (isFull(stack))
    stack->array[++stack->top] = item;
    printf("%d pushed to stack\n", item);

    second question
    on codeblocks it evaluates to 13 if x=5 intially.
    x=++x + x++;

    • nascardriver

      Hi prince!

      The push function is not a problem, because you're not assigning a new value to @stack, you're only modifying it's members. Think of it like this

      This obviously isn't problematic.

  • Ujjwal pratap

    #include "stdafx.h"
    #include <iostream>
    int main()
        int x;
        std::cout << "enter :";
        std::cin >> x;
        ++x;                            or when we use x++, then results are same. Why??
        std::cout << x;
        return 0;

    • nascardriver

      Hi Ujjwal!

      The only difference between ++prefix and postfix++ is their return value.
      ++prefix increments and then reads the value to be returned.
      postfix++ reads the value to be returned, then increments, then returns the value which was stored prior to the increment.
      When you're not using the return value of the oparator++, use ++prefix.

  • Nux

    I don't understand this exemple.

    "What value does this program print? The answer is: it’s undefined."

    From the lesson 3.1 (

    I have learn than the Pre-increment operator ++ have an operator precedence of 3 and the operator = an operator precedence of 15

    So this is a define situation. Pre-increment should be resolve first like this: x = (x++);
    and the Incrematation of x should be resolve before the assignement of the x's copy to x

    Or am I missunderstanding something ?

    • Alex

      It seems like it should be as you say (which is why this gets so many C++ programmers into trouble). C++ actually gives the compiler a LOT of leeway in determining the order of evaluation. For example, although you might code a() + b(), either a() or b() could be evaluated first.

      With side effects, this gets a bit weird. We know that x++ both returns the value of x (which happens immediately upon evaluation), and applies a side effect to x that will increment its value. However, the compiler is given a lot of leeway to determine when to schedule the ++ part of the operation. In practice, the ++ could happen before the assignment, or after. If you (or anyone else) want to do more reading, look up the concept of "sequence points" (or sequencing, as of C++11).

  • Nux

    I think the std:: is missing here.

    Here is a version with std:: added

  • Samira Ferdi

    Which is the better or best practices? using x++ or x+=1 for using in a function?

    • nascardriver

      Hi Samira!

      There's no difference. I use ++x unless the 1 is variable and I might change it in the future.

    • Eric

      Hi Samira,

      Logically the two statements are the same (apart from the side affect) but there *could* be a difference in the machine code generated by the compiler.

      The unusual syntax of ++n (or —n) was included in the original C language because the statement would likely result in a single machine code operation often called INC (or DEC) for increment/decrement.  This would presumably perform much better than having to load 2 registers and using an ADD operation.

      But this is highly dependent on the compiler and the CPU instruction set.  And a good compiler/optimizer should be able to reduce n += 1 to an INC instruction anyway.

      Intel x86 CPUs have the INC/DEC instructions but Raspberry Pi computers do not, for example.

      I like to use ++n where it makes sense in case my code is compiled on a CPU that supports the faster increment/decrement operations.

  • Samira Ferdi

    Can we use increment/decrement that adding in real number like adding/subtract 0.1 or 0.001?

    Is there in C++ that implementing other operators in expression like increment/decrement?

    • nascardriver

      Hi Samira!

      The default increment and decrement operators are fixed at 1. Later on you'll learn about defining own data types and own operators which you could use to implement such behavior.

  • Byron

    Hi Alex,
    I wanted to check whether my compiler evaluates the left or right argument first, using the code you provided in this lesson. In theory, one of the two values should have been 11 and the other 12, no? In fact both return 12. Am I understanding things incorrectly here?

    • Alex

      You're seeing unexpected results because you're breaking one of the most broken rules in C++: Don't use a variable with side effects applied more than once in an expression. Operator++ applies a side effect, so you're running afoul of this rule, and the result you're seeing is the result of undefined behavior.

      Here's a program I whipped up that will tell you your evaluation order:

      gen() returns 9 the first time it's called, and 8 the second time. By looking whether left is 8 and right is 9 or vice-versa, we can determine which operand got evaluated first.

      • Byron

        Thanks! And apologies for forcing you to repeat the same thing again.
        I thought I was not using it twice in an argument actually as I was using the operator only once. I guess it's the variable that I should count and not how many times I am using the operator.

      • Rohit

        Hi Alex.

        I'm failing to understand your program. The way I see it, the function "gen()" is called two times with its own local scope each time, so it would return 9 every time. Getting called once wouldn't have any effect on any subsequent calls. This is especially true considering "x" is a static integer.

        Well that's what I had initially thought, anyway. What am I understanding incorrectly? How do the 2 calls to gen() provide different results?

        • nascardriver

          Hi Rohit!

          @x is in the scope of @get, but @x's lifetime begins with the first call to @gen and ends with the program's exit, not with the end of @gen. You can treat @x as a global variable with limited scope.

          Lesson 4.3 — Static duration variables

          • Rohit

            I see, thanks!

            So it's because of the static variable, which comes in the future. I was thinking "static" was another way of having a constant variable but that's where the English language messed me up, haha.

  • Michael

    Hi Alex,
    The post increment operator has a higher precedence than assignment operator. Doesn't it mean that

    will be executed in the same way as

    which has a defined behavior?

    • Alex

      No. The higher precedence means x++ is evaluated first. That evaluation means x++ will be evaluated to produce the value x. The actual increment part is not guaranteed to happen immediately (think of post-increment as "increment at some point in the future"). So it could be the assignment happens first, or the ++ happens first.

      This was probably originally done for performance reasons, but is one of those annoying quirks of the language that you have to learn not to do.

  • Aditya

    So, is it best if we don't use the increment/decrement operators at all?

    • Alex

      You should feel free to use the increment and decrement operators. Just don't use the variables you're using those operators on more than once in a given statement.

  • The Perplexed Programmer

    Reminds me of a joke.

    "Hey, how to increment a variable C?"

  • Lim Che Ling

    Hi, Alex,

    I am very confused about prefix and postfix ++ and the explanation term "evaluates and increment" as well as the rvalue and lvalue in this context.

    int x = 5;
    int y = x++;  //postfix ++ will Evaluate x, then increment x

    In this e.g., I understand in this way "First, a memory location x with value 5 is made a temporary copy with temp copy which has value 5. Then 'Evaluate x' means 'assign value of temp copy 5 to y', discard temp copy, incrementing x from 5 to 6."

    So with same token,

    int x = 5;
    ++x++; //This evaluates to ++(x++) due to postfix has higher precedence than prefix
    So on the postfix x++, it will Evaluate x, then increment x.

    In this case, "First, a memory location x with value 5 is made a temporary copy with temp copy which has value 5(now has two memory locations with value 5). Then 'Evaluate x' means 'working on ++x' which would evaluate to temporary copy increased to 6 then discard temporary copy, then incrementing original x from 5 to 6.

    Somehow, my understanding lacks of incorporation of r-value and l-value concept inside and so it seems compiler should compile though I think something is amiss.

    • Alex

      Don't worry about r-values and l-values in this context. int x = 5 is just memory location x being initialized with value 5. x++ evaluates to 5 means that the compiler reduces that expression to the singular value 5. So even though x is incremented to 6 (as a side effect), the value 5 is assigned to y, since that's what x++ evaluated to.

  • P8yan

    "If the ++ is applied to x before the assignment, the answer will be 1 (prefix operator++ increments x from 1 to 2, but it evaluates to 1, so the expression becomes x = 1)."

    I believe "prefix" above was meant to be "postfix".

  • Stephane

    Hi Alex, What do you mean by te outputting of x modifying the console?
    Great tutorial, thanks

    • Alex

      Outputting the value x to the console changes the state of the console such that it now displays the value of x, whereas before it did not.

  • Hi Alex. Can you please explain this program. This is the same program given in example in this chapter but I made a change in the line where the add function is called. I added pre-decrement operator. When I executed your example without any change, the output was 12, which means that my compiler (code blocks) first operates on the right argument. If it is so, then this program should have given 11 as output but the output given is 10.

    Thanks in advance

    • Alex

      Rule: Don't use a variable that has a side effect applied to it more than once in a given statement. If you do, the result is undefined.

  • John

    Hi! Great tutorials!
    I have a bit of a question...
    I wrote a code that finds the prime numbers up to 100. It works fine, but I can't figure it out how to deal with the first prime number, witch is 2.
    I put there a separate if statement, just to output 2, and after that it goes normal for the rest of the numbers.
    But I would like to make the code more generic, without working separately just for 2.

    Here's the code:

    If I exclude this part:

    the code outputs prime numbers starting from 3...
    I have tried to change the initial values of dividend and divisor but without any success.

    • Alex

      I'd probably just move this part:

      inside the while loop. That way your while loop logic will work for the number 2. I can't think of a way to not special-case it.

    • Liam

      I edited your code slightly (and used it as a means of practice) to give the user the ability to set their own limit.

  • MJ

    Great content, as always.

    Minor clarification point: Since x++ evaluates first, then assigns, I think this line in your second example should be changed from:


    This would help the reader and is (I think) more in line with the definition provided.

  • Pritam Das

    void main()

       int x =5, y;
       y =x++ + ++x;
       cout<<++y<<" "<<y++;
    the output is
    14 12

    dear alex ,plz tell me the logic behind the output,

    • Alex

      Rule: Don't use a variable that has a side effect applied to it more than once in a given statement. If you do, the result is undefined.

  • John

    "C++ does not define the order in which function arguments are evaluated."

    In the example below, does this mean that it is not guaranteed that line 11, i.e. array[x++], will be evaluated to 10 for every compiler?

    x = 1
    x = 2

    Is it correct wording to say that array[x++] evaluates to 10 in this example?

    • Alex

      Your program doesn't call any functions with multiple arguments, so the order of evaluation issue isn't applicable here.

      array[x++] will always evaluate to 10 here.

      • John

        So, looking at line 11 i the code above, i.e.

        From the Table in section 3.1 we find the precedence and the associativity for the post-increment (x++) and the array subscript operators [], respectively

        2 L->R    ++    Post-increment    (x++)
        2 L->R    []    Array subscript

        They have the same precedence level 2, and the same associativity L->R. How is the rule applied now? It's not evaluated L->R, more from inside and out, how does the compiler read the code array[x++] (what rules are applied)?

        Just a note, the pre-increment operator (++x) has a lower order of precedence, and associative R->L, i.e.

        3 R->L    ++    Pre-increment    (++x)

        Replacing line 11 in the code with


        • Alex

          In the post-increment case, the subscript operator is evaluated first (because it's to the left of the postfix-++), and a function named operator[] is called with x++ as a parameter. At this point, x++ gets evaluated to the value of x, which is passed into operator[], which uses that value to subscript the array.

          It works the same way in the pre-increment case, except ++x evaluates to x+1, which is the value that gets passed into the subscript function and used to subscript the array.

  • Bernat

    I don't see the problem in the last one, I mean, if ++ is evaluated first then x will be 2 and then the = will be evaluated which will make x be 2. If the = is evaluated first x = x which is one, and then the ++ will be evaluated which will cause x to be 2, right? I guess I'm doing it wrong in some part, but I don't know how.

    • Alex

      I've updated the lesson with a little more detail about how these expressions evaluate. Have a re-read and let me know if you have additional questions.

      • Vlad

        I think I might know the cause of his confusion cause as I've scratched my head for a few seconds as well.

        "If the ++ is applied to x before the assignment, the answer will be 1 (postfix operator++ increments x from 1 to 2, but it evaluates to 1, so the expression becomes x = 1).

        If the ++ is applied to x after the assignment, the answer will be 2 (this evaluates as x = x, then postfix operator++ is applied, incrementing x from 1 to 2)."

        In the first paragraph, I think it should be prefix operator instead of postfix. Thanks for the awesome tutorials!

  • Arsala

    #include <iostream>

    using namespace std;

    int main()
        int a=5;
        cout<<a++<<" "<<a++<<" "<<++a<<" "<<a++<<" "<<++a<<endl;
        return 0;

    I have problem with this code , I am not understanding the output result that is 9 8 10 6 10 rather according to me it should 5 6 8 8 10
    please reply

  • Andreas

    question 1:

    question 2:

    question 3:


  • int main()
        int x = 1;
        x = x++;
        std::cout << x;

        return 0;

    What value does this program print? The answer is: it’s undefined. If the ++ is applied to x before the assignment, the answer will be 1. If the ++ is applied to x after the assignment, the answer will be 2.

    Could you explain this to me more????

    • Alex

      Unfortunately, the answer is somewhat complicated, and has to do with something called sequence points. A sequence point is a point in the program where it's guaranteed that all side effects from previous evaluations have been performed. Between sequence points, the order of side effects resolution is indeterminate.

      The challenge with this particular program is that the side effects from postfix operator++ and the assignment operator aren't separated by a sequence point, so the compiler is free to apply those side effects in either order.

      If the ++ is applied after the assignment: First x++ evaluates to 1. That 1 is assigned to x. Then the ++ is applied to x, which increments it to 2.
      If the ++ is applied to x before the assignment: First x++ evaluates to 1. The ++ is then applied, changing the value of x to 2. The value of 1 from the previous evaluation is then assigned to x, leaving x with the final value of 1.

      Both of these are valid interpretations of how to resolve the expression in C++, and different compilers may choose to do it differently.

  • Max Payne

    Hello Alex !
    I have a problem !
    #include <iostream>

    int main()
        int x = 10;
        int z = (++x) + (x++);
        std::cout << z;
        return 0;

    Why This code is producing the result 23 ?
    I think it should produce the result 22....

    • Alex

      When you use a variable with a side effect applied more than in a single statement, the result is undefined.

      On your compiler, it produces 23. On another compiler, it may produce 22. On a third compiler, it may produce something else.

  • saratha


    int ch=20;

    output I got was 21 21 20.somewhere I read calculations takes place from right to left.Printing takes place from left to right.kindly explain

Leave a Comment

Put all code inside code tags: [code]your code here[/code]