[Insight-developers] Postfix versus Prefix operators

Brad King brad.king at kitware.com
Fri May 27 09:24:41 EDT 2011


On 05/27/2011 09:00 AM, Bill Lorensen wrote:
> I noticed a comment you made in a review asking why cppcheck prefers
> prefix operators over postfix operators. I did a little searching and
> found this discussion regarding  the advantage of prefix over postfix:
> http://www.thunderguy.com/semicolon/2002/08/13/prefer-prefix-operators-over-postfix/
> 
> Perhaps other c++ experts may comment.

Everything on that page is accurate.  However, it is possible to write a
postfix operator for one's own class that does not need to save the value
in a temporary.  See below for an example.  In C++0x the tag_postincr
constructor will be able to call the real copy constructor to avoid the
duplication.

Most of the performance discussion is moot given modern compiler optimizers.
The code below depends on the "Return Value Optimization" (RVO) to construct
the return value of the postfix increment operator directly in its final
destination rather than in an unnamed temporary which is then copied to the
final destination.  Compilers also implement a "Named RVO" (NRVO) which will
identify a local variable that is used as the only return value and allocate
it directly in the final destination (when the code is inlined).  Therefore
the two approaches will have no difference in practice.

The other arguments on the page are not performance related and should be
considered important.  I always use prefix unless I really need postfix.

-Brad


#include <iostream>
class A
{
  struct tag_postincr {};
  A(A& a, tag_postincr): Value(a.Value) // Duplicate copy constructor
    { ++a; } // Increment copied value afterward
  int Value;
public:
  A(): Value() {}
  A(A const& a): Value(a.Value) {}
  A& operator++() { ++this->Value; return *this; }
  A operator++(int) { return A(*this, tag_postincr()); }
  int GetValue() const { return this->Value; }
};

int main()
{
  A a;
  A ar1 = ++a;
  std::cout << "++a return = " << ar1.GetValue() << std::endl;
  std::cout << "++a after  = " << a.GetValue() << std::endl;
  A ar2 = a++;
  std::cout << "a++ return = " << ar2.GetValue() << std::endl;
  std::cout << "a++ after  = " << a.GetValue() << std::endl;
  return 0;
}


More information about the Insight-developers mailing list