In C and many of its derivatives, i++
increments i
and evaluates to the value of i
before it was incremented, and ++i
increments i
and evaluates to the value of i
after it was incremented.
I can see the reasoning for a specific increment operator; many processors at the time had a special increment opcode that was faster than addition and conceptually "increment" is a different idea from "add," in theory having them be written differently might make code more readable.
What I don't understand is the need for the pre-increment operator. Can't any practical use for it be written like this?
#This...
x = i++;
#becomes this:
x = i;
++i;
Is there a historical reason I don't know about, maybe? Were you unable to "throw away" the return values of operators in primordial versions of C?
1) Increment Operators: The increment operator is used to increment the value of a variable in an expression. In the Pre-Increment, the value is first incremented and then used inside the expression. Whereas in the Post-Increment, the value is first used inside the expression and then incremented.
We use increment operators in C to increment the given value of a variable by 1.
Pre-Increment Operator in C Therefore, we can say that the pre-increment operator increases the value of the variable first and then use it in the expression. Syntax: b = ++a; For example, if the initial value of a were 5, then the value 6 would be assigned to b.
In C, ++ and -- operators are called increment and decrement operators. They are unary operators needing only one operand. Hence ++ as well as -- operator can appear before or after the operand with same effect. That means both i++ and ++i will be equivalent.
One reason is that it allowed for the generation of efficient code without having any fancy optimisation phases in compilers, provided that the programmer knew what he (or she) was doing. For example, when copying characters from one buffer to another, you might have:
register char *ptr1;
register char *ptr2;
...
for ( ... ) {
*ptr1++ = *ptr2++; /* post-increment */
}
A compiler that I once worked with (on a proprietary minicomputer) would generate the following register operations for the assignment:
load $r1,*$a1++ // load $r1 from address in $a1 and increment $a1
store $r1,*$a2++ // store $r1 at address in $a2 and increment $a2
I forget the actual opcodes. The compiler contained no optimisation phase yet the code that it generated was very tight providing that you understood the compiler and the machine architecture. It could do this because the hardware architecture had pre-decrement and post-increment addressing modes for both address registers and general registers. There were no pre-increment and post-decrement addressing modes as far as I recall but you could get by without those.
I believe that the DEC minicomputers on which C was originally developed had such addressing modes. The machine that I worked on wasn't made by DEC but the architecture was pretty similar.
An optimisation phase was planned for the compiler. However, it was mostly used by systems programmers and when they saw how good the generated code was, implementation of the optimisation phase was quietly shelved.
The whole rationale for the design of C was to allow the creation of simple and portable compilers that would generate reasonably efficient code with minimal (or no) intermediate code optimisation. For this reason, the increment and decrement operators and also the compound assignment operators played an important role in the generation of compact and efficient code by the early C compilers. They were not just syntactic sugar as suggested by Niklaus Wirth et al.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With