Pre-increment or post-increment in C/C++ -

Pre-increment or post-increment in C/C++

Most C or C++ programmers are completely clear about the behavior of the ++ operator [and ] and the result of expressions that employ it. However, what if the return value is unused? Does it matter whether the code uses ++i or i++ ? This article looks at the finer points of compiler code generation and why that choice might matter.

Although any C programmer could easily learn another programming language and quickly become proficient in it, C continues to be the dominant language for embedded software programming. One reason for this is the large reservoir of expertise in the language, and most embedded C programmers understand the low-level nuts and bolts of the language. However, as embedded developers are always concerned with writing efficient code and minimizing overheads, being “proficient” is not enough.

There are still facets that may come as a surprise, even to those with years of experience.

A case in point is the pre-increment/post-increment problem. Not long ago, I was working on a conference paper about using C++ for embedded applications. I sent the paper out to the embedded compiler and programming language experts on the Mentor Embedded development tools team and asked them to review my work. As expected, I got some detailed and helpful feedback, but I was left wondering about one particular suggestion. I had written something like this:

  for (i=0; i<10; i++)

This seemed straightforward, but I was told that in terms of C++ style, it would be better to write this:

  for (i=0; i<10; ++i)

I was mystified. I thought that I was entirely clear about the two forms of the ++ operator.

i++ and ++i
We are all familiar with the ++ operator (and its sibling –). Applying this operator increments the variable. Well, that is what appears to happen. Let’s look more closely.

++ is really a pair of operators: pre-increment and post-increment. The former increments the value of a variable and returns the resulting value; the latter increments the value of the variable and returns the value prior to the increment. So, if a variable x initially contains the value 3, the following expressions yield different results:

  y = ++x; // y==4, x==4
  y = x++; // y==3, x==4

The effect on x is the same in both cases, but y gets a different value.

This is all straightforward. The programmer needs to be careful to use the correct operator to achieve the required result in an expression.

Throwing away the result
A C program is built by formulating a number of expressions, each of which yields a result. However, an expression by itself cannot be executed. To create an executable unit of code, an expression must be converted into a statement by adding a semicolon at the end. Here are two statements:


They both achieve the same result: the variable x is incremented. Any value that the expressions yielded is lost. So, from a programmatic point of view, the two statements are identical.

Consider how each version of the operator may work. Pre-increment simply performs the operation on the variable and returns its value. Post-increment requires that the previous value be retained somewhere, ready for return, so some additional storage may be required. Thus, the two statements are potentially able to generate different code. The pre-increment version is clearly preferable.
Imagine that we were defining the int data type (only we will call it Integer) from scratch in C++. We might have something like this:

class Integer
  Integer& operator++()
    x_ += 1;
    return *this;
  const Integer operator++(int)
    Integer temp = *this;
    return temp;
  int x_;

The additional storage for the post-increment, temp, is clear.

In a real implementation of a complex data type (a class), the overhead may be much greater than just the additional word of storage and a little extra code.

Of course, a smart compiler would almost certainly pick this up and optimize the unnecessary storage away. It is, however, much better to understand the semantics of the language and write defensively – code exactly the functionality that you intend and do not rely on a compiler to make up for your shortcomings.

What Does “Increment” Mean?
Having dabbled with C++ here, we are reminded that operators can be redefined to do anything – although taking advantage of this capability and creating operators that perform functions radically different from standard is very bad programming practice.

However, it is not necessary to stray quite so far to see some interesting behavior from the ++ operator. Look at this code:

  int *ptr;
  ptr = (int *)0x8000;

What value does ptr end up with? Many programmers would assume 0x8001, as there is a perception that, in C/C++, “increment” means “add 1”. But that is not the real meaning of the word – it really means “advance the value in a meaningful way”. So, the actual answer (assuming 32-bit integers) is 0x8004. The compiler knows how many bytes an int occupies – 4 – and advances the pointer accordingly. Even though, on the surface, this seems counter-intuitive, it would make sense if you were stepping a pointer through an array of integers.

So, again the behavior of this seemingly simple operator is more complex than might be assumed.

Colin Walls has over thirty years experience in the electronics industry, largely dedicated to embedded software. A frequent presenter at conferences and seminars and author of numerous technical articles and two books on embedded software, Colin is an embedded software technologist with Mentor Embedded [the Mentor Graphics Embedded Software Division], and is based in the UK. His regular blog is located at: . He may be reached by email at .

30 thoughts on “Pre-increment or post-increment in C/C++

  1. I remember back in the day people writing ++i rather than i++ because the Borland C compiler generated different (and faster) code for ++i.

    However, any compiler worth its salt should figure that a free-standing i++ means exactly the same as i++ and shoul

    Log in to Reply
  2. Mr. Walls, with all due respect, this is what happens when someone thinks that a proficiency in C language automatically means an ability to write a proper C++ code as well. Or worse, not only write code but being a recognizable industry person that writes

    Log in to Reply
  3. Gato: With all due respect to you, I believe that you misunderstood what I said. In my original example, i was a simple int – that is why I was mystified about any possible difference between ++i and i++. My colleagues were simply picking me up on style.

    Log in to Reply
  4. To this day I still use the preincrement form when it doesn't matter because an old C compiler I used to use (Apple's own MPW C) had such an awful optimizer. It really did make a difference. I even have a hard time adapting to coding standards that specify

    Log in to Reply
  5. There's other pitfalls with post/pre increment I think are worth considering. For example, an older IAR-branded 8051 compiler I've used makes choices when using such operators whether to generate in-line code or to call a library object in the event the o

    Log in to Reply
  6. Seems like nit-picking to me. If you are worried about every load and store operation, or whether there is one copy on the stack or two copies; then you've got no business writing in C++ anyway. And any decent compiler is going to collapse even the given

    Log in to Reply
  7. While post- and pre- inc/dec will have defined behavior in C or C++, it's not always obvious to every person who might read the code. I think the well seasoned programmer would do a good service to his associates by avoiding heaping incrementers or decrem

    Log in to Reply
  8. I didn't know that pre increment was better than post increment when used in a single expression but i used it that way anyways because it is easier for me to find a ++i than a i++ when reading a piece of code.

    Log in to Reply
  9. I agree, and would like to suggest extend your guideline to 'operator precedence' as well. For readability, instead of writing
    It would be much more readable and maintainable to write
    y=a+(b*c) //intent is clear
    or split it into two lines as you s

    Log in to Reply
  10. Coding standards should not blindly dictate a one-size-fits all habit, just because some box-of-rocks got promoted to management via the Peter Principle and wants to drag everyone down to their level. Coding standards should give a useful rule for a usefu

    Log in to Reply
  11. I have been writing very complex C++ code for over 20 years (including a stint debugging various commercial compilers), and still do today. It is good to see articles like this every so often, if only to remind us of what we already know! 🙂

    Log in to Reply
  12. It occurred to me that this is a perfect illustration why C++ is mistrusted in embedded programming. The for(…,i++) construct is a familiar iterator: discarded value, well-known and expected side effect. However, due to C++ power, suddenly there's a poss

    Log in to Reply
  13. “yes, in the old days for(…++i) would be faster and smaller than for(…i++).nnA modern compiler should figure it out and give you the same result. I just compiled a small test with gcc and the binary output was EXACTLY the same.nnnBy the way what h

    Log in to Reply
  14. “Hey i would like to know that in C ++a=20 gives error and in C++ it compiles without an error ……why is it so?? And can anyone gives me brief knowledge about lvalue and rvalue ?? “

    Log in to Reply
  15. “Incrementing a void pointer should be illegal since the compiler doesn't know the size of the elements its working with. The IAR compiler will generate an error. At the least, if the compiler allows it, it's a bad (and possibly dangerous) coding practic

    Log in to Reply
  16. “One of my favorite tech interview Qs is:nint a=1;nint b=2;nint c==a+++b;nDoes it compile? If not, what needs to change. After running what are the values of a, b, & c?nnNot because I expect them to know the answer, but to see how they approach the p

    Log in to Reply
  17. “Probablement depuis le du00e9but de l'annu00e9e derniu00e8re u00e0 regarder avec attention, une image de chance de microblogging laissez-moi savoir Rolex, d'abord juste sentir tru00e8s beau, mais montre que le blanc ne savait pas qu'il u00e9tait en

    Log in to Reply
  18. “I would have liked to have seen an analysis of the generated assembly. Is there a savings to using one of the operators over the other?nnI would expect to see ++i do something like fetch and increment, use (i.e. as the value of the expression) and write

    Log in to Reply
  19. “addition of 3 variables can be broken down into a 2 step process .ntemp= ++a + ++a;nb=temp + ++a;nfirst ++a makes the value as 6 and the second ++a makes it 7. since both the variables used in temp is pointing to a, temp=7+7=14.nnext step is simple. b

    Log in to Reply
  20. “If this were merely a style issue, then the suggested modification to the for loop can be what it is. As a coding issue, however, it is a moot point and suggests that the for loop is misunderstood. The i++ operation is run separately from the i lt 10 co

    Log in to Reply
  21. “i used this code for form show.when we start first time this form will behind the main screen next time not happening this and after idel the application in 20 min it will hide first time then not happening.How to solve this issue nfrmFlagConfirm objFrmF

    Log in to Reply
  22. “For the longest time, I was under the impression that the use of prefix increment vs postfix increment made no difference in cases where the result was not being used in the same statement. But a few years (and a couple jobs) ago, working on heavily-load

    Log in to Reply
  23. “This is funny. I had a SW interview and the interviewer asked me the same question. I replied with the same answer as above. I was offered the job but I took another. However, for those wondering, variable a is post-incremented over b's possible pre-incre

    Log in to Reply

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.