Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 3

PRE/POST INCREMENT

I found very drastic execution of C program in some cases..

Can u say why it is like this..?

C Syntax (Toggle Plain Text)

• int main(){
•  
• {
• int j=5;
• std::cout << ((++j) + (++j)) + (j++) << std::endl;
• }
• {
• int j=5;
• std::cout << ((++j) + (++j)) << std::endl;
• }
• {
• int j=5;
• int x = ++j;
• x += ++j;
• x += j++;
• std::cout << x << std::endl;
• }
• {
• int j=5;
• j = ++j + ++j + j++;
• std::cout << j << std::endl;
• }
•  
• return 0;
• }

The output is:


21
14
20
22
At least on my computer.

I think the problem here is that the operator ++j will take the value of j after the whole expression evaluation. This
explains the second case in my example, j is pushed, then incremented twice, then the values of both ++j terms are
set to the value then (which will be 7), and are finally added. If you apply the same logic to the first case, the initial
value of j is 5, so that is the return value of expression j++, then after two ++j and one j++, the final value of j is 8, so 8
+ 8 + 5 = 21.

But the last case, I can't figure this one out, let me think about it a bit more. I think I will avoid using complex
expressions with many ++ operators in the future.

Increment operators
I guess this really is a case of undefined behaviour, because there is so much space for weird optimizations because
of ambiguous operator priority... in any case, I think I cracked the last case giving 22. This is a pseudo-assembly
code I can come up with to explain it: so please contact me on shashiknth0@gmail.com

C Syntax :

• // ((++j) + (++j)) + (j++) gives the following:


• PUSH J,R1
• COPY R1,R2
• INC R1,1 //do first ++j
• INC R1,1 //do second ++j
• INC R1,1 //do j++
• //now, R1 = 8, R2 = 5
• COPY R1,RES //add ++j to result
• ADD R1,RES //add ++j to resul
• ADD R2,RES //add j++ to result
• //now RES = 21
•  
• // j = ++j + ++j + j++; gives the following:
• PUSH J,R1
• INC R1,1 //do first ++j
• INC R1,1 //do second ++j
• //now, R1 = 7
• COPY R1,R2 //copy initial value of j
• //since initial value of j (R2) is equal to result of j++, the addition can be done now.
• ADD R1,R1 //optimized addition of j = j + j to simply j += j
• ADD R2,R1 //now add "initial value" of j.
• //now R1 = 21 (3 x 7)
• INC R1,1 //do j++
• MOVE R1,J
• //now J = 22

Increment operators
It's called side effects, it is generally not a good idea to program statements like this because of the unpredictability of
them. This unpredictability comes partially from operator precedence, but not entirely. The increment and decrement
operators have higher precedence than multiplication, division, and modulus, and postfix versions have higher
precedence than prefix version. As a result, they are most likely not applying when you think they are.

In the second version, the pre-increment operators are applying to the temporary values produced, not j itself (temp
values in red):
int j = 5, x;

//theoretical step by step:


x= ++j + ++j + j++;

/*becomes*/ x = ++5 + ++5 + 5++;


/*becomes*/ x = ++6 + ++6 + 5;
/*becomes*/ x = 8 + 8 + 5;
/*becomes*/ x = 16 + 5;
/*becomes*/ x = 21;
/*becomes*/ x = 21;

I have absolutely no clue about the third situation, but I get the same results as you on both VC++ 2008 and
Code::Blocks... It is best not to speculate on undefined behavior, simply knowing that it's undefined should be
enough.

You might also like