Click here to Skip to main content
15,881,204 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
how the expression works in c c++ and java
a=10;
c=++a + ++a;
output:
In C :22
In Java : 23
In C++ : 24

Why this happens can anyone explain me. what is the actual working of the ++ increment here and why the answers are different.
Posted
Comments
PIEBALDconsult 2-Aug-15 23:55pm    
Just don't do that.
Sergey Alexandrovich Kryukov 3-Aug-15 1:23am    
Why going in for C++-like syntax's casuistic?
Does it present any theoretical of fundamental interest? Certainly not. The particular order of calculation is just a play of design and implementation peculiarities.

Can it be a training for human intellect? To certain extent, yes, but who cares how much of such "trained intellect" one has?

Is it important for in practical programming? Certainly not, because any style which prevents correct intuitive understanding of the code would be utterly impractical.

—SA
[no name] 6-Aug-15 14:16pm    
But from a view of a "Parser/Compiler Programmer" this is still a valid question... if I write a Parser/Compiler I like to give a deterministic answer on such a question.
Sergey Alexandrovich Kryukov 6-Aug-15 14:37pm    
Yee.. only very boring. :-)
—SA
[no name] 6-Aug-15 15:05pm    
That is _very_ true... howsoever something can be more than true :-)
Bruno

1 solution

Hoo boy!
Pre- and post- fix increment and decrement operations are pretty easy in theory, it's only when people get creative that you get problems in practice. Basically, a prefix (++i or --i) says to increase or decrease the value before you use the variable, so the variable has the new value immediately:
C#
i = 10;
x = ++i + 5;

Can be read as:
C#
i = 10;
i = i + 1;
x = i + 5;

and similarly for the -- version:
C#
i = 10;
x = --i + 5;

Can be read as:
C#
i = 10;
i = i - 1;
x = i + 5;

The postfix version (i++ or i--) does the same thing, but after the variable has been used:
C#
i = 10;
x = i++ + 5;

Can be read as:
C#
i = 10;
x = i + 5;
i = i + 1;

And similarly
C#
i = 10;
x = i-- + 5;

Can be read as:
C#
i = 10;
x = i + 5;
i = i - 1;


Is that it? It's a bit...simple...

Yes, it is. Or, perhaps not.

It is simple, if you use it in simple ways - as an array indexer for example:

C#
x = myArray[index++];

Or as a loop increment:

C#
for (i = 0; i < 10; i++)
   {
   WriteLine(myArray[i]);
   }

But after that, you are into a world of confusion and pain! 

For example, what does this leave as a value of i:

C#
int i,j;

i = 10;
for (j = 0; j < 5; j++)
    {
    i = i++;
    }


The answer is: unchanged. i remains at 10. Why? Think of it like this: what does this look like if we expand it?

C#
int i = 10;
i = i++;


If we write this in C#, then the IL looks like this:

.line 14,14 : 13,24 ''
IL_0001:  ldc.i4.s   10                    Push a constant value '10' to the stack, 4 byte integer, 
IL_0003:  stloc.0                          Pop the top of the stack into local number 0
.line 15,15 : 13,21 ''
IL_0004:  ldloc.0                          Push local number 0 to the stack 
IL_0005:  dup                              Duplicate the top of the stack
IL_0006:  ldc.i4.1                         Push a constant value '1', 4 byte integer
IL_0007:  add                              Pop the top two stack items, add them, and push the result
IL_0008:  stloc.0                          Store the top of the stack in local number 0
IL_0009:  stloc.0                          Store the top of the stack in local number 0


What? In expanded C# code, that comes back as:

C#
int i = 10;
int j = i;
int k = j;
k = k + 1;
i = k;
i = j;


Which is rather strange...because you could throw away the three lines in the middle without affecting the results.  

It shouldn't do that, should it?

Yes. Yes, it should: i++ is a postfix operation: It says, "remember the value of i, then increment i by one, and then return the value you remembered".

So what you have told the compiler to do is ignore the result of the increment by overwriting it with the value you started off with.

Interestingly, if you try it in the Visual Studio C++ compiler...it doesn't... because it handles it differently! 

So, now we have the first reason why you have to be careful when you start using increment and decrement operators  for real: it's effectively a side effect, a whole line of code inserted into your line, and if you don't think very carefully, it won't do what you think. 

int i1 = i; i1 = i1 + 1; i = i

The trouble comes when you start mixing operations on the same line:
C#
i = 10; x = ++i + i++;
The problem is that the language specification does not define exactly when pre- and post- fix operations should occur! Which means that it's implementation specific exactly what you get as a result: The value of i should always be the same: 12 but the value of x can be different depending on the compiler (and to an extent on the target processor - ARM for example has built in pre- and post- fix increment and decrement to it's "machine code" LOAD operations, so it would be quite likely that an efficient compiler would use them directly) Should it be executed as:
C#
i = 10; 
i = i + 1; 
x = i + i; 
i = i + 1; 
Which gives the result 22 or as
C#
i = 10; 
i1 = i; 
i = i + 1; 
x = i1 + i; 
i = i + 1;
Which gives 21 Or as
C#
i = 10; 
i1 = i; 
i = i + 1; 
x = i + i1; 
i = i + 1;
which also gives 21 by a different route.
And bear in mind that the compiler does not have to evaluate the two operands of "+" in left to right order, so it could even give some very strange and unexpected results! Like 23... So avoid combining them: use them for "simple expressions" such as incrementing an array index each time round a loop, but don't get fancy, or your code may well fail in interesting ways...
 
Share this answer
 
Comments
Shmuel Zang 3-Aug-15 2:29am    
5+.
Frankie-C 3-Aug-15 7:43am    
5ed. Side effects have to be avoided...
[no name] 6-Aug-15 17:04pm    
"and similarly for the -- version: "
Still after some correction of you I think it makes no sense. There is something mixed up :(
OriginalGriff 6-Aug-15 17:21pm    
It's the Markup processor - it's not supposed to activate inside code blocks, and it's supposed to honour the "don't use Markup" flag. But...
Hopefully the new version the Hamsters are deploying will be rather less intrusive... :sigh:

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900