* Old Wolf:
The side effect is that 'i' is incremented.
The expression evaluates to (i + 1).
"side effect" is a clearly-defined term in the Standard.
Talking about a "primary and only effect" only seems to
muddy the waters, to me.
Then you shouldn't have used the term in its more common meaning
earlier in the thread... ;-)
What is this 'little more' of which you speak?
The page you link to doesn't say.
Does, too. (I'm on the level.)
++i and i++ have /exactly the same/ side-effect.
For a specific definition of "side-effect" that renders your own earlier
comment in this thread,
"However, in my experience, people write side-effect code
more often with i++ than they do with ++i"
meaningless.
Did you mean, "people use i++ more often ++i"?
Well, I don't believe it.
Can you give a code example of where i++ does something that
++i doesn't?
The standard specifies a copy operation for i++, and no such for ++i.
i++ means exactly the same thing as (++i - 1), if we don't
run into integer overflow.
Nope.
First, formally, you're talking about built-in types, I presume. Even
there (and disregarding overflow) your expression is not quite equivalent.
It cannot be used for 'bool', preserving the type of the expression.
Second, in practice, as noted above, the standard specifies a copy operation
for i++, but none such for ++i, which means that in the program below, although
both expressions are formally Undefined Behavior instead of the more
reasonable Unspecified, in practice the ++i-1 expression can at most produce
x = 2, while the j++ expression can at most produce y = 1:
#include <iostream>
#include <ostream>
int main()
{
int i = 0;
int j = 0;
int const x = (++i - 1) + (++i - 1); // Formally UB.
int const y = (j++) + (j++); // Formally UB.
std::cout << x << ", " << y << std::endl;
}
Hence, in code that has UB in this way, but works with a given version
of a given compiler with given options (not uncommon), it's absolutely
not a good idea to replace (i++) with (++i-1).
Summing up: the purported equivalence does not hold formally, and it
does not hold in practice.
There is no possible piece of code where the behaviour is
undefined, but changing 'i++' to '++i' renders the behaviour
well-defined. [where 'i' is an int]
Probably you meant to write,
"changing 'i++' to '(++i - 1), disregarding overflow,".
If so then I think that's right: for 'int', and disregarding overflow.
However, people tend to write side-effect based code more often with
i++, because that's what it's made for -- it's a convenience notation
for side-effect based code, as of 2005 generally premature optimization.