Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Post increment operator behavior [duplicate]

Possible Duplicate:
Pre & post increment operator behavior in C, C++, Java, & C#

Here is a test case:


void foo(int i, int j)
{
   printf("%d %d", i, j);
}
...
test = 0;
foo(test++, test);

I would expect to get a "0 1" output, but I get "0 0" What gives??

like image 233
Benoit Avatar asked Sep 19 '08 00:09

Benoit


People also ask

Does increment work on double?

However, it does use the operator to increment isolated integer variables. It does not use the operator with floats or doubles.

How does post increment operator work?

The post increment operator is used to increment the value of some variable after using it in an expression. In the post increment the value is used inside the expression, then incremented by one. if the expression is a = b++; and b is holding 5 at first, then a will also hold 5.

Which operators is post increment?

Post-increment is an increment operator, represented as the double plus (a++) symbol followed by an operator 'a'. It increments the value of the operand by 1 after using it in the mathematical expression.

Why post increment is used in for loop?

Pre increment directly returns the incremented value, but post increments need to copy the value in a temporary variable, increment the original and then returns the previous made copy.


Video Answer


2 Answers

This is an example of unspecified behavior. The standard does not say what order arguments should be evaluated in. This is a compiler implementation decision. The compiler is free to evaluate the arguments to the function in any order.

In this case, it looks like actually processes the arguments right to left instead of the expected left to right.

In general, doing side-effects in arguments is bad programming practice.

Instead of foo(test++, test); you should write foo(test, test+1); test++;

It would be semantically equivalent to what you are trying to accomplish.

Edit: As Anthony correctly points out, it is undefined to both read and modify a single variable without an intervening sequence point. So in this case, the behavior is indeed undefined. So the compiler is free to generate whatever code it wants.

like image 197
Benoit Avatar answered Nov 09 '22 00:11

Benoit


This is not just unspecified behaviour, it is actually undefined behaviour .

Yes, the order of argument evaluation is unspecified, but it is undefined to both read and modify a single variable without an intervening sequence point unless the read is solely for the purpose of computing the new value. There is no sequence point between the evaluations of function arguments, so f(test,test++) is undefined behaviour: test is being read for one argument and modified for the other. If you move the modification into a function then you're fine:

int preincrement(int* p)
{
    return ++(*p);
}

int test;
printf("%d %d\n",preincrement(&test),test);

This is because there is a sequence point on entry and exit to preincrement, so the call must be evaluated either before or after the simple read. Now the order is just unspecified.

Note also that the comma operator provides a sequence point, so

int dummy;
dummy=test++,test;

is fine --- the increment happens before the read, so dummy is set to the new value.

like image 28
Anthony Williams Avatar answered Nov 09 '22 00:11

Anthony Williams