Schilcote Schilcote - 3 months ago 19
C Question

What purpose does the pre-increment operator serve in C?

In C and many of its derivatives,

and evaluates to the value of
before it was incremented, and
and evaluates to the value of
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?

x = i++;
#becomes this:
x = 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?


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.