------- Comment #5 from hayward at loup dot net 2007-04-22 16:37 ------- Subject: Re: postfix increment semantics implemented incorrectly
> Why do you say could blow the stack, the C++ standard actually mentions an > optimization where the copy constructored is removed and there is no extra > variable. It is called named return value optimization which removes the need > for the extra stack, basically the return value is actually a pointer that is > passed into the function and then initialized that way. > > So I don't see your point still. An optimizing compiler could, in theory, optimize out copy construction and only copy the object portions modified in the body of the postfix operator. In practice that increment body could be far more complex than simply incrementing a 32 bit counter and the return value could be also be used for arbitrarily complex manipulations. In these cases the current interpretation will by necessity involve a complete copy. Consider a trivial example of a large n dimensional matrix object where calling postfix increment should increment every component in the entire matrix. Assuming the matrix is actually used in the expression, there is no inexpensive way to perform the postfix increment without post evaluating the method. > The result you are seeing is exactly, I mean exactly what the C++ standard says > the results should be as b = a++; is translated exactly as b = a.operator++(0); > and not as b = (tmp = a, a.operator++(0), tmp); In fact this is worse than > what you are suggesting the C++ standard says there is an extra tmp variable on > the stack to begin with while before with named return value, you don't have > one. It appears you are not completely undestanding my suggestion. There exists a difference between postfix syntax and postfix semantics. I am not by any means saying that a++ would not be equivalent to a.operator++(0) as the operator notation is simply syntactic sugar. I am suggesting that they of course have equivalent semantics as is specified, but that the semantics would be different from prefix ++a and a.operator++(). If the operator doesn't has postfix semantics, it is both misleading and additional syntax of limited use. No expensive temporary copies need be involved as in the return by value example you give... that would defeat the return by reference argument I'm making. Implementation would simply involve creating a subsequent sequence point for any and all post rvalue operations. For example: b = a++; // postfix operator syntax b = a; // equivalent semantics without postfix operator ++a; Or if you prefer method syntax: b = a.operator++(0); // postfix method syntax b = a; // equivalent semantics without postfix method a.operator++(); > Actually it would violate the C++ standard and break existing code as people > don't have to return the copy. Your example shows exactly why your proposal > change will break valid code. I realize a change could break code that depends on the current implementation and doesn't return a copy by value. Maybe that's reason enough to not change an implementation, but I think not. I'm making the case that the implementation does not implement the intent of the C++ standard. There is the "letter of the law" and the "spirit of the law" and without a more explicit specification, it is understandable how we could argue for either interpretation. That is why if there is ambiguity I gravitated to the expected, semantically consistent, more efficient, and simpler case. > I think you need to go back and read more about overloading operators as it > seems like you don't understand that overloading operators can sometimes change > the semantics if the overloaded operator changes them as shown by > your example. The semantics of an expression are dependent upon the method implementation, of course, but also upon order of operation which includes operator associativity. It was my understanding that order of operation and associativity are the same regardless of basic or overloaded operator status. The whole notion of postfix operation is pretty simple to grasp (that the operation is performed "after" it is used in the expression) and it's disappointing that although it could be very efficient for arbitrary objects, it simply is not as it is implemented now. Since I am now clear that it is implemented as you would intend, I will hold peace if you do not wish to champion my interpretation. I at least want someone in a position to affect things to fully grasp the point I am making. Perhaps yours is the more widely adopted interpretation of the spec as written, but surely you see the benefit of post expression semantics? I think it would be useful if someone could get the specification clarified and annotated on this point... Once again, thanks for the feedback, and cheers :-) - Mike -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31652