NO

Author Topic: Why I get this output ?  (Read 13081 times)

boral

  • Guest
Why I get this output ?
« on: October 17, 2012, 07:25:47 PM »
As per the calling convention of c , we know that arguments are passed to a function from right to left when a function call is encountered. So the output of the program :
#include<stdio.h>
 
main( )
{
  int  a = 1 ;
printf ( "%d %d %d",a, ++a, a++ ) ;
}
 is 3 3 1
This is alright.....but why the output of the following program is 2 2 3 instead of 2 2 1.
#include<stdio.h>
 
main( )
{
  int  a = 1 ;
printf ( "%d %d %d",a++, ++a, a ) ;
}
Please explain the flow of control.  :(

shazam

  • Guest
Re: Why I get this output ?
« Reply #1 on: October 17, 2012, 10:40:14 PM »
On my cell phone so cant type much right now

But read up on how postfix and prefix operators work

++a
a++



boral

  • Guest
Re: Why I get this output ?
« Reply #2 on: October 18, 2012, 05:55:02 AM »
For the first program the flow of control is this:
Firstly, 1 is passed through the expression a++ and then a is incremented
to 2. Then result of ++a is passed. That is, a is incremented to 3
and then passed. Finally, latest value of a, i.e. 3, is passed. Thus in
right to left order 1, 3, 3 get passed. Once printf( ) collects them it
prints them in the order in which we have asked it to get them
printed (and not the order in which they were passed). Thus 3 3 1
gets printed.
For the second program the flow of control should be [as far as I know]:
Firstly 1 is passed through a...then 1 is incremented to 2 and then 2 is passed through ++a....then 2 is passed through a++.....then 2 gets incremented to 3....i.e. 1 2 2 is passed from right to left...so the program must print 2 2 1....but it prints 2 2 3.....why ???

CommonTater

  • Guest
Re: Why I get this output ?
« Reply #3 on: October 18, 2012, 06:04:11 AM »
Because it's doing the pre-increment and post-increment processing before printing... in the same memory loacation as A, so that by the time it goes to print the final value a is already incremented twice.
 
:D When I run into stuff like this, I generally remind myself that I'm getting "too cute" and need to get back to real programming. :D
 



 
« Last Edit: October 18, 2012, 06:06:19 AM by CommonTater »

boral

  • Guest
Re: Why I get this output ?
« Reply #4 on: October 18, 2012, 06:50:39 AM »
@CommonTater I am a beginner....so please explain me the flow of control in details....otherwise please point out the fallacy in my logic of flow of control for the 2nd program.

CommonTater

  • Guest
Re: Why I get this output ?
« Reply #5 on: October 19, 2012, 06:41:29 AM »
@CommonTater I am a beginner....so please explain me the flow of control in details....otherwise please point out the fallacy in my logic of flow of control for the 2nd program.

I pretty much did that.  The thing solves right to left but prints left to right so by the time it's printing the final a value it's already done the two increments... It's not much more complex than that.

There is such a thing as "undefined behaviour" where unexpected, even erratic, results can and do happen.  This, because the compiler can't account for every possible combination of events... This little bit of yours probably qualifies. When playing in undefined behaviour you may get 223 from Pelles and 123 or even 122 from some other compiler.  You won't know till you test it and even then you should not rely on it.

The classic example of undefined behaviour is A = A++ / A-- * A  you are changing the value of A more than once in a step, you can't trust the result.
 

 
« Last Edit: October 19, 2012, 06:48:20 AM by CommonTater »

Offline Bitbeisser

  • Global Moderator
  • Member
  • *****
  • Posts: 772
Re: Why I get this output ?
« Reply #6 on: October 19, 2012, 07:53:09 AM »
As a general rule, specially for newbies: it is a good idea to separate arithmetic and output. That would make things like this probably a bit clearer...

Ralf

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
Re: Why I get this output ?
« Reply #7 on: October 19, 2012, 09:39:19 AM »
Why you get the wrong result?
I compiled:
Code: [Select]
n (int argc, char *argv[])
{
int  a = 1 ;
printf ( "%d %d %d\n",a, ++a, a++ ) ;
a = 1 ;
printf ( "%d %d %d\n",a++, ++a, a ) ;
return 0;
}
And I got the right result: 331 and 221.
The output is deterministic in C, function parameters are evaluated and pushed on the stack from right to left, the printf function shows the values as specified in the format string (from left to right).
The code flow is simple as follows:

1st printf
- push the value of parameter (a) then increment it (postincrement): push 1, a=a+1=2
- Increment the variable (preincrement) then push the value: a=a+1=3, push 3
- Just push the variable: push 3
The printout is 331

2nd printf
- Just push the variable: push 1
- Increment the variable (preincrement) then push the value: a=a+1=2, push 2
- push the value of parameter (a) then increment it (postincrement): push 2, a=a+1=3
The printout is 221

printf get the values on the stack (pushed values) as input parameters.

I think that you are using a broken compiler.
If your compiler is PellesC, it is a broken outdated version: update to the last version.
Anyway the correct output is the one I showed, if you get something different there is no way: that compiler is broken and not compliant.
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide

JohnF

  • Guest
Re: Why I get this output ?
« Reply #8 on: October 19, 2012, 03:59:09 PM »
Why you get the wrong result?
I compiled:
Code: [Select]
n (int argc, char *argv[])
{
int  a = 1 ;
printf ( "%d %d %d\n",a, ++a, a++ ) ;
a = 1 ;
printf ( "%d %d %d\n",a++, ++a, a ) ;
return 0;
}
And I got the right result: 331 and 221.
The output is deterministic in C, function parameters are evaluated and pushed on the stack from right to left, the printf function shows the values as specified in the format string (from left to right).
The code flow is simple as follows:

1st printf
- push the value of parameter (a) then increment it (postincrement): push 1, a=a+1=2
- Increment the variable (preincrement) then push the value: a=a+1=3, push 3
- Just push the variable: push 3
The printout is 331

2nd printf
- Just push the variable: push 1
- Increment the variable (preincrement) then push the value: a=a+1=2, push 2
- push the value of parameter (a) then increment it (postincrement): push 2, a=a+1=3
The printout is 221

printf get the values on the stack (pushed values) as input parameters.

I think that you are using a broken compiler.
If your compiler is PellesC, it is a broken outdated version: update to the last version.
Anyway the correct output is the one I showed, if you get something different there is no way: that compiler is broken and not compliant.

I don't think that's right, using ++ that way can/will lead to different results depending on the compiler.

As Tater said it is undefined behaviour.

Read the C-FAQ.

John
« Last Edit: October 19, 2012, 04:58:44 PM by JohnF »

CommonTater

  • Guest
Re: Why I get this output ?
« Reply #9 on: October 19, 2012, 04:19:06 PM »
For an example of how this kind of thing can go wrong....
Code: [Select]
a =1;
printf("%d %d ", a, a++);
// a bunch of other code
printf(" %d\n", a);

boral

  • Guest
Re: Why I get this output ?
« Reply #10 on: October 19, 2012, 06:36:22 PM »
Thanks to all of you very much....this discussion helped me a lot.
CommonTater specially thank u very much .... the thing that u have said is given slightly here...in sections 3.4.3, 3.4.4 and 6.5 of the following pdf.
http://www.linux2you.dk/JTC1/SC22/WG14/www/docs/n1336.pdf
« Last Edit: October 19, 2012, 07:10:13 PM by boral »

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
Re: Why I get this output ?
« Reply #11 on: October 20, 2012, 04:40:11 PM »
While I've never get into an evaluation sequencing that doesn't strictly follow right to left order, from which my mistaken belief, the standard states, at ยง6.5.2.2 sentence 10 that the parameters evaluation sequence is undefined.
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide

JohnF

  • Guest
Re: Why I get this output ?
« Reply #12 on: October 20, 2012, 05:11:36 PM »
I tried VC6 - it gives a different result to PelesC.

John

CommonTater

  • Guest
Re: Why I get this output ?
« Reply #13 on: October 20, 2012, 07:26:55 PM »
Interestingly... the problem is not that anyone is getting a "wrong" result... the problem is there's no "right" result.


boral

  • Guest
Re: Why I get this output ?
« Reply #14 on: October 21, 2012, 06:14:01 AM »
I tried VC6 - it gives a different result to PelesC.

John

What result does VC6 gives ?