Dean
Dean

Reputation: 1153

Fully understand prefix increment (++) operation

I have the following code and I expect the output is:

foo(0) -- 2   /* 1*2 */
foo(2) -- 12  /* 3*4 */
foo(4) -- 30  /* 5*6 */

but I've got

foo(2) -- 4
foo(4) -- 16
foo(6) -- 36

instead. Can someone explain to me what happened?

include <stdio.h>

int main()
{
    int counter;    /* counter for loop */

    counter = 0;

    while (counter < 5)
        printf("foo(%d) -- %d\n", counter, ((++counter)*(++counter)));

    return (0);
}

Upvotes: 4

Views: 872

Answers (4)

zwol
zwol

Reputation: 140659

Once you've used ++ -- prefix or postfix -- on a variable, you can't use it again on the same variable until after the next sequence point. If you do, the behavior of the code is undefined -- the compiler is allowed to do anything it wants.

There are no sequence points between the two (++counter) expressions in your code, so you've run afoul of this rule. You have to write something like this, instead:

while (counter < 5) {
    printf("foo(%d) -- %d\n", counter, (counter+1) * (counter+2));
    counter += 2;
}

Upvotes: 13

Alexander Gessler
Alexander Gessler

Reputation: 46617

(++counter)*(++counter) is actually undefined behaviour in C since a variable is modified twice without a sequence point (i.e. a ;) in between. The result may vary across different compilers. Some may opt-in to format your hard disk instead, but luckily your compiler hasn't.

Apart from this, there's little to be understood about prefix-increment. bar(++i) is shorthand for

i += 1;
bar(i);

Upvotes: 4

pm100
pm100

Reputation: 50190

you are expecting it to do

++c = 1 * ++c = 2

= 1*2 = 2

What is actually happening is

++c = 2 * ++c = 2

= 4

As other have pointed out - this is undefined behavior. the compiler is not required to reveal its inner working unless you force it to by breaking complex statements up into smaller pieces

Upvotes: 0

Guvante
Guvante

Reputation: 19203

Prefix increment means the increment is done before the remainder of the operations. To my knowledge the official requirement is that the evaluation of ++counter is not the original value.

It is likely being expanded as an increment before the statement like so:

 counter = counter + 1;
 counter = counter + 1;
 printf("foo(%d) -- %d\n", counter, ((counter)*(counter)));

Which would create the behavior you are seeing. My recommendation is to avoid stress testing these kinds of corner cases too much.

Upvotes: 0

Related Questions