I don't agree with you +Paul, one of the essential learning curves IMHO, is
to learn the compiler behavior and the deep language specifications and
details.

I'm going to explain how GCC treat this code, but I have to mention first
that GCC compiler is not a straight TOP-DOWN or BOTTOM-UP compiler, it's a
mix of both, so it treats expressions by dividing them into sub expressions,
and figure the priority of expressions to be executed.

First I'll put it into a simpler form:

int j=1, k;
> k = (++j) + (++j);
>

k will be *6* after this last line, *why*?

To calculate this expression, the compiler divides it into two branches: *
++j* and *++j*. Calculate each branch separately, and then add the result of
each branch to formulate the result and store it in k.
Let's first imagine the j in memory, it's now a variable containing the
value *1*.

++j in itself means, j=j+1 AND then return the value of j
So we have two operations, increase j by 1, and the value is found in j,
in the other branch, similarly, increase j by 1, and the value is found in
j,

Thus,
First branch: j=j+1 [store *2* in j], the value is found in j,
Second branch: j=j+1 [store *3* in j], the value is found in j.

Finally,
First branch's value, is located in j, and the same for second branch, j
contains *3*, so retrieving *3 twice*, add them, the result will be *6*.

To test this more, let's try it by another incremental method:

int j=1, k;
> k = (j++) + (j++);
>

here k will be *2*,
First let's define j++: it means return the value located in j, then j=j+1
j contains *1*,
First branch: j++ => return j, j=j+1
Second branch: j++ => return j, j=j+1

Before getting into any more arithmetic operations, k's value is determined
by the previous two returns, and j's value at this point was *1*, so k = *1
+ 1*, which give the value *2*.

If you examine the value of j directly after this statement, it'll be *3*.

Now getting a little variety,

int j=1, k;
> k = (j++) + (++j);
>

j contains *1*,
First branch: return j, then j=j+1,
Second branch: j=j+1, return the value of j

Second branch will increase the value of j, which is the compiler priority
now, so j's value will be *2*, now we have two j returns to be added, *2 + 2
*, which will result in *4*. Finally j will increase by one and its final
value will also be *3*.

Here is the sequence of computation:
j=j+1, return j as first branch, return j as second branch, add the two
returns and store it in k, j=j+1 {which got a lower priority in the
execution sequence}.

The other side,

int j=1, k;
> k = (++j) + (j++);
>

First branch: j=j+1, return j
Second branch: return j, j=j+1

And here is the sequence: j=j+1, return j from first branch, return j from
second branch, add the two returns and store them into k, j=j+1.

*Finally, the analysis of the OP code:*

int j=2,k;
> k=++j + ++j + ++j;
>

j contains *2*,
The second line will get divided into sub expressions similar to this one:

k = *(*(++j) + (++j)*)* + *(*++j*)*;
>

We have the first branch ((++j) + (++j)) [which contains in itself two sub
branches], and the second branch (++j)

Now,
First branch: was previously showed how it's calculated and its result here
will be *8* (and j contains now *4*)
Second branch: j=j+1, return j (so it will return *5*)

So we have *8 + 5*, which gives *13* to be stored into k.


I'm not sure if this could be judged as *a bug* or *as designed*, probably
the latter because, very complicated operations require this sequence for
execution so it should work like that and not anything else, and I could be
wrong about that. I don't have other compilers to test though, but one thing
to remember always is that, the compiler is not that straight structured in
its execution, not from top to down and from left to right neatly.
Of course in real production, you don't need this. A loop is safer by all
sides, starting from readability and traceability.

-- Amahdy
www.amahdy.net



On Mon, Aug 15, 2011 at 19:25, Paul Smith <[email protected]> wrote:

> The behaviour of your code is undefined.
>
> That means you should never write code in this manner - there's no
> need of multiple increment operations within the same expression.
>
> Paul Smith
>
> [email protected]
>
>
>
> On Sun, Aug 14, 2011 at 10:54 AM, sumon <[email protected]>
> wrote:
> > #include<stdio.h>
> > void main()
> > {
> >        int j=2,k;
> >        k=++j + ++j + ++j;
> >        printf("%d",k);
> >
> > }
> >
> > In GCC compiler why is it  giving 13??
> >
> > --
> > You received this message because you are subscribed to the Google Groups
> "google-codejam" group.
> > To post to this group, send email to [email protected].
> > To unsubscribe from this group, send email to
> [email protected].
> > For more options, visit this group at
> http://groups.google.com/group/google-code?hl=en.
> >
> >
>
> --
> You received this message because you are subscribed to the Google Groups
> "google-codejam" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected].
> For more options, visit this group at
> http://groups.google.com/group/google-code?hl=en.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"google-codejam" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/google-code?hl=en.

Reply via email to