TITLE: canonical form for operator ++ prefix and postfix PROBLEM: Art Shelest I was wondering why Stroustroup declared prefix increment operator as returning a value and postfix as returning a reference in his "Design and Evolution of C++" book: RESPONSE: Eric Bowman , 13 Feb 96 I never thought I would have the opportunity to say this, but "Stroustrup is wrong." God save my soul. Art: class A { public: A operator++(); A& operator++(int); } After some through, I've decided that they are both incorrect, in traditional meaning. Eric: The "canonical" way to declare prefix & postfix ++ (and --, obviously) is: A &operator++(); // prefix A operator++(int); // postfix The essence of ++ & -- in C is as follows (K&R 2nd ed., Section 2.8): "The unusual aspect is that ++ and -- may be used either as prefix operators (before the variable, as in ++n), or postfix (after the variable: n++). In both cases, the effect is to increment n. But the expression ++n increments n before its value is used, while n++ increments n after its value has been used." And Stroustrup, _C++ Programming Language_, 2nd ed., r.5.2.5: "The value obtained by applying a postfix ++ is the value of the operand. The operand must be a modifiable lvalue.... After the result is noted, the object is incremented by 1. The type of the result is the same as the type of the operand, but it is not an lvalue." r.5.3.1: "The operand of prefix ++ is incremented by 1. The operand must be a modifiable lvalue.... The value is the new value of the operand; it is an lvalue." This suggests (or perhaps even requires) an implementation like: A& A::operator++() { this->Increment(); return *this; } // prefix A A::operator++(int) { A temp(*this); ++(*this); return temp; } // postfix Art: For example, with declaration above I can write: A a1,a2; ++a1++ = a2; // freaky. BTW: which increment will be first? Eric: Incidentally, it is well-defined that ++ works right-to-left; thus the postfix operates first, then the prefix. Using Stroustrup's declarations: The postfix is evaluated first, which returns a reference (to what I'm not sure...hopefully not a local variable from A::operator++), then this reference is passed to the prefix operator, and a value (unnamed temporary object) is returned. It is not an lvalue, even though my compiler (MSVC4) will compile Stroustrup's way. Incidentally, if the postfix operator returns a reference to itself, then it's *not* behaving in correct "postfix operator fashion". Using the "correct" declarations: The postfix is evaluted first, returning a value object (temporary), which is incremented using the prefix operator, and returned-by-reference. The r-value is placed in this temporary object, and is hence lost. (I *think* a so-called ANSI-conformant compiler isn't supposed to allow an unnamed temporary to be an l-value, but I could be wrong; again, MSVC compiled this with no warnings.) Art: which is not good in conventional sense. The only "correct" declaration I could find was const A& operator++() and const A& operator++(int) which seem to behave in conventional way as far as L-value goes. Eric: Close, but not quite. First, if the postfix operator returns a reference, what is it a reference to? If it is a reference to *this, then it's not behaving like a true postfix operator. If it is returning a reference to a local variable it creates, then its broken. If it returns a reference to anything else, it's weird. The postfix operator should return the value of the object before it is incremented, period. You may return a const object from the postfix operator; I don't think it will affect things either way, but there's no real reason to do it that I'm aware of. Secondly, it's probably bad to return a const reference from the prefix operator. Doing so would generally prohibit the following: do { *(++anIter) = foo; } while (anIter != something.end()); In this case, we increment anObject, then assign to it. This is useful and there's no reason to prohibit it by returning a const reference (unless you *really do want to prohibit it*, in which case it's a dandy idea and a fine use of a language feature to enforce a design decision. Meyers would be proud.). Art: Anyone has a clue why Bjarne would like postfix increment to return reference and prefix -- the object? Eric: 'Cause he's only human?