Did not imply? Original question did not _state_ that explicitly, but it
did _imply_ it very clearly. The original question stated the increment
operators in question "add 1" and did not mention anything about those
operators being user-defined. That's "implying" in my book.
He did not mention that he meant built-in either, so we apparently
interpreted the implication differently. I was inclined to interpret it the
way I did, because, I think, this is much more generic case and that
therefore it would be valuable to mention the efficiency issue. Guess how
many people still use postix ++ in "for" loops, using STL iterators and not
built-in types?
The value obtained by applying a postfix ++ is the value that the
operand had before applying the operator.
[Note: the value obtained is a copy of the original value ]
The purpose of this note is simply to indicate that the result is not a
lvalue. It doesn't in any way indicate that there's is some kind of a
preliminary step in the evaluation of post-increment, when this copy is
made so as to save the old value from being destroyed. There's no need
to do that.
You said that post-increment returns "copy of the original object, which
is created before the original object is modified".
Firstly, this statement imposes a strict ordering on the process of
evaluation of post-increment. This is always incorrect in case of
built-in operators. There are no temporal orderings in the C++ program
besides those imposed by sequence points.
Secondly, you state that the copy in question is created by copying the
object in its original state. There's noting in the standard that says
that the copy is created in this fashion. In case of built-in
post-increment the copy of the old value can be obtained by subtracting
1 from the new value. I.e. the copy can still be created even _after_
the side effect of post-increment took place.
C'mon, read two more sentences after your cut of my citation of the
standard. I reproduce it again.
****
The value obtained by applying a postfix ++ is the value that the
operand had before applying the operator.
[Note: the value obtained is a copy of the original value ] The
operand shall be a modifiable lvalue. The
type of the operand shall be an arithmetic type or a pointer to a
complete object type. After the result is
noted, the value of the object is modified by adding 1 to it, unless
the object is of type bool, in which case
it is set to true. [Note: this use is deprecated, see annex D. ] The
result is an rvalue
****
What draws my attention is the line "After the result is
noted, the value of the object is modified by adding 1".
In my book, this is temporal ordering. "The result is noted" = recorded,
stored, whatever, and then the object (original) is modified. This ordering
has nothing to do with sequence points though, as all steps must be
completed before the next sequence point. But there is, apparently,
ordering. And I meant only that.
At the same time, I have to admit, that compilers may not follow this line
exactly. Out of curiosity,
I played with source
int f(int& i, int& j)
{
++i;
j++;
return j; // to pick up the side effect
}
and some of it's variations with VC6 and looked at the assembly produced the
in speed optimization release mode. The number of operations "attributable"
to each line was not necessarily in favour in ++i, so I tend to agree that
one should not generalize the case of user-defined operator's efficiency to
that of the built-in one.
Rgds
ad