Incrementing (adding 1 to) and decrementing (subtracting 1 from) a variable are so common that they have their own operators in C. There are actually two version of each operator — a prefix version and a postfix version.
|Prefix increment||++||++x||Increment x, then evaluate x|
|Prefix decrement||––||––x||Decrement x, then evaluate x|
|Postfix increment||++||x++||Evaluate x, then increment x|
|Postfix decrement||––||x––||Evaluate x, then decrement x|
The prefix increment/decrement operators are very straightforward. The value of x is incremented or decremented, and then x is evaluated. For example:
int x = 5; int y = ++x; // x is now equal to 6, and 6 is assigned to y
The postfix increment/decrement operators are a little more tricky. The compiler makes a temporary copy of x, increments x, and then evaluates the temporary copy of x.
int x = 5; int y = x++; // x is now equal to 6, and 5 is assigned to y
In the second line of the above example, x is incremented from 5 to 6, but y is assigned the value of the copy of x, which still has the original value of 5.
Here is another example showing the difference between the prefix and postfix versions:
int x = 5, y = 5; cout << x << " " << y << endl; cout << ++x << " " << --y << endl; // prefix cout << x << " " << y << endl; cout << x++ << " " << y-- << endl; // postfix cout << x << " " << y << endl;
This produces the output:
5 5 6 4 6 4 6 4 7 3
On the third line, x and y are incremented/decremented before they are evaluated, so their new values are printed by cout. On the fifth line, a temporary copy of the original values (x=6, y=4) is sent to cout, and then the original x and y are incremented. That is why the changes from the postfix operators don’t show up until the next line.
A side effect is a result of an operator, expression, statement, or function that persists even after the operator, expression, statement, or function has finished being evaluated.
Side effects can be useful:
x = 5;
The assignment operator has the side effect of changing the value of x permanently. Even after the statement has finished executing, x will have the value 5.
Side effects can also be dangerous:
int x = 5; int nValue = Add(x, ++x);
C++ does not define the order in which function parameters are evaluated. If the left parameter is evaluated first, this becomes a call to Add(5, 6), which equals 11. If the right parameter is evaluated first, this becomes a call to Add(6, 6), which equals 12!
As a general rule, it is a good idea to avoid the use operators that cause side effects inside of compound expressions. This includes all assignment operators, plus the increment and decrement operators. Any operator that causes a side effect should be placed in it’s own statement.
Note that side effects are not confined to operators, expressions, and statements. Functions can also have side effects, which we will discuss in the section on global variables (and why they are evil).
|3.4 — Sizeof, comma, and arithmetic if operators|
|3.2 — Arithmetic operators|