You are here:

C++/Increment operators

Advertisement


Question
Hello Sir,
     Why preincrement operator is faster than postincrement?  

Answer
For the build in integer types it may well not be (and, as with the rest of this subject, the same goes for the pre- and post- decrement operators as well). So in C ++k and k++ were the same, k had to apply to a built in type that supported these operations, and it is probable that the machine code generated for each would be equally as efficient if not identical.

However in C++ we can use operator overloading to create types that support operators such as pre- and post increment using the same syntax as used by the built in types. So in C++ k could be an object of a user defined type and ++k and k++ may call operator++ functions for this type. It is these cases where pre-increment is usually faster and more efficient than post-increment.

Why would this be you might ask. Well pre-increment performs the increment operation on the object to which it applies and returns the value of the object after the operation has been applied. This is easy to do:

   class KClass
   {
   public:

   // ...

       // Pre-increment operator for KClass
       KClass & operator++() { ++m_position; return *this; }

   // ...

   private:
       pointer_type      m_position;

   // ...
   };

I have shown parts of a definition for a class called KClass. It stores some sort of a pointer to represent the current position represented by the class. The position can be changed, and one such method is to increment it. The pre-increment operator for KClass increments the position member m_position and returns a reference to itself. This is consistent with what pre-increment does: increment the object and return the current object value.

Post-increment is more complicated. It increments the value of the object but returns the value of the object _before_ it was incremented. As the object has now been incremented this means the before increment value must be saved before the increment occurs and this copy returned after the increment has occurred. Worse, because the copy returned is temporary and local it cannot be returned by reference, it has to be returned by value incurring at least one additional copy:

   class KClass
   {
   public:

   // ...

       // Post-increment operator for KClass
       KClass operator++(int)
       {
         KClass copy(*this);
         ++(*this);      // Calls KClass pre-increment operator
         return copy;
       }

   // ...

   };

Above I have shown an implementation of the post-increment operator for KClass. It makes a copy of the current object, performs a pre-increment operation to actually update the object, and returns the copy by value.

Note that I call the pre-increment operator from the post-increment operator. This is a common idiom and ensures they both perform the increment part of their operation in the same way. As such operations are often trivial they are often defined as inline functions, so the overhead of the call is avoided. Of course if the increment operation is more complex and the functions are not inlined then there may well be an additional overhead.

Note also that the signature of the pre- and post- increment operators differs. The post increment operator takes a dummy int parameter, whereas the pre-increment operator takes no parameters. This means the post increment operator has to be called with a single int parameter, which could be a source of further overhead, although for inlined cases a good compiler should be able to optimise this away.

A further implication of the semantics of post-increment is that the types that support it have to be copyable.

So in cases where it does not matter C++ people prefer to use pre-increment (or pre-decrement for that matter). By does not matter I mean that either post- or pre- increment (or decrement) could be used without changing the meaning as in the following:

   ++i;

However you should use the appropriate form where it does matter, for example where the increment is part of some other expression, as in the following where using pre-increment would change the meaning:

   array_of_values[index++] = get_value();

This is all very well you might say but surly such cases are rare? Not so much since the C++ standard library. Here we have container types (vector, list, etc), and the idea of sequences within them over which we can iterate using iterators. These iterator types function something like pointers, and in fact to obtain a value (or more likely a reference) from an iterator we use dereference operators like * and ->. Note that a pointer can be used as an iterator, and some implementations do use pointers for some container iterator types. Here is an example of iterator use:

   void PrintVectorInt( std::vector<int> vec )
   {
       std::vector<int>::iterator iter( vec.begin() );
       std::vector<int>::iterator finished( vec.end() );

       for ( ; iter != finished; ++iter )
       {
         std::cout << *iter << " ";
       }
  
       std::cout << '\n';
   }

Here I loop around the sequence from the beginning of the vector to the end of the vector printing out each value in the vector. I do this by first initialising an iterator loop variable called iter to the beginning of the passed in vector vec. I define the end point as an iterator object called finished (so I do not have to keep evaluating vec.end()). The end iterator of standard library containers represents a position one past the last element of the container. I loop while iter is not finished. Each time around I pre-increment iter.

If I had incremented iter using post-increment then unless the vector iterator type is a built in pointer type the iterator class' post-increment operator would be called, which would incur additional overhead.

As more and more people start using the features of the C++ standard library the use of iterators will become more and more common, and it is likely that in such cases post increment will be performed by a user defined function incurring additional overhead.

So get into the habit of using pre-increment (or decrement) when it does not matter.  

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


Ralph McArdell

Expertise

I am a software developer with more than 15 years C++ experience and over 25 years experience developing a wide variety of applications for Windows NT/2000/XP, UNIX, Linux and other platforms. I can help with basic to advanced C++, C (although I do not write just-C much if at all these days so maybe ask in the C section about purely C matters), software development and many platform specific and system development problems.

Experience

My career started in the mid 1980s working as a batch process operator for the now defunct Inner London Education Authority, working on Prime mini computers. I then moved into the role of Programmer / Analyst, also on the Primes, then into technical support and finally into the micro computing section, using a variety of 16 and 8 bit machines. Following the demise of the ILEA I worked for a small company, now gone, called Hodos. I worked on a part task train simulator using C and the Intel DVI (Digital Video Interactive) - the hardware based predecessor to Indeo. Other projects included a CGI based train simulator (different goals to the first), and various other projects in C and Visual Basic (er, version 1 that is). When Hodos went into receivership I went freelance and finally managed to start working in C++. I initially had contracts working on train simulators (surprise) and multimedia - I worked on many of the Dorling Kindersley CD-ROM titles and wrote the screensaver games for the Wallace and Gromit Cracking Animator CD. My more recent contracts have been more traditionally IT based, working predominately in C++ on MS Windows NT, 2000. XP, Linux and UN*X. These projects have had wide ranging additional skill sets including system analysis and design, databases and SQL in various guises, C#, client server and remoting, cross porting applications between platforms and various client development processes. I have an interest in the development of the C++ core language and libraries and try to keep up with at least some of the papers on the ISO C++ Standard Committee site at http://www.open-std.org/jtc1/sc22/wg21/.

Education/Credentials

©2016 About.com. All rights reserved.