#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2012
    Posts
    3
    Rep Power
    0

    About Prefix And Postfix Operators ..


    void main()
    {
    int y,x=5;
    y=++x + ++x;
    printf("%d\n",x);
    printf("%d",y);
    getch();
    }


    hai guys ... please look at the above simple code , where i declared a variable named x and assigned it with a value 5 . my question here is in the expression part . ( Y=++x + ++x ) ... after executing the program i got the output as

    output
    --------
    7
    14 ..

    but i am unable to identify whats going on in this program . please make it clear to me . thanks in advance ..
  2. #2
  3. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    > but i am unable to identify whats going on in this program
    Don't worry about it - no one else can either.
    The code is fundamentally flawed and analysis is pointless. If your tutor claims to "know" the answer, please give them the rest of this post, then find a better tutor to learn from. Oh, and one more thing, main returns an int, NOT void.




    I'm reposting something I wrote some time ago for another forum.

    - Changing compiler options changes things.
    - Changing compiler changes things.
    - Even changing the compiler version changes things!.
    In short - "DON'T GO THERE!"


    This is a catalogue of some experiments showing unspecified behaviour and undefined behaviour.

    This was inspired by yet another long bout of explanation in a recent thread, so I thought it was time to dust off a bunch of compilers, and compare.

    This is the test code.
    Code:
    #include <stdio.h>
    
    int f1 ( void ) {
      printf( "f1 called = 1\n" );
      return 1;
    }
    int f2 ( void ) {
      printf( "f2 called = 2\n" );
      return 2;
    }
    int f3 ( void ) {
      printf( "f3 called = 3\n" );
      return 3;
    }
    int f4 ( void ) {
      printf( "f4 called = 4\n" );
      return 4;
    }
    int f5 ( void ) {
      printf( "f5 called = 5\n" );
      return 5;
    }
    
    /* Although * happens before +, there is NO guarantee that */
    /* f1() will always be called after f2() and f3() */
    /* http://c-faq.com/expr/precvsooe.html */
    void test1 ( void ) {
      int result;
      printf( "Precedence is not the same as sub-expression evaluation order\n" );
      result = f1() + f2() * f3() - f4() / f5();
      printf( "Result=%d\n", result );
      printf( "inline=%d\n", f1() + f2() * f3() - f4() / f5() );
    }
    
    /* The nature of 'before' and 'after' is poorly understood */
    /* http://c-faq.com/expr/evalorder2.html */
    void test2 ( void ) {
      int i = 3, j = 3;
      int r1 = ++i * i++;
      printf( "Multiple side effects are undefined\n" );
      printf( "R1=%d, i=%d\n", r1, i );
      printf( "R2=%d, j=%d\n", ++j * j++, j );
    }
    
    int main ( ) {
      test1();
      test2();
      return 0;
    }
    test1() gives a well-defined answer, as one would expect.
    What is unspecified however, is the order in which f1() to f5() are called.
    That is, the order of the printf statements varies (quite amazingly).

    test2() is just broken code with no redeeming features. Yet despite this, people often claim they know how the result is worked out.
    One set of results will however make you think about it!

    All tests were done using XP as the host OS, with the exception of the gcc test, which was done under Ubuntu.

    The only compiler flags used were to test the effect of optimisation.
    For most of the Windows compilers, this is basically a choice between "optimise for space" or "optimise for speed".

    The compiler results are presented in approximately alphabetical order.


    Borland C++ Compiler 5.5, With Command Line Tools, Version 5.5.1
    No Optimisation
    01 Precedence is not the same as sub-expression evaluation order
    02 f2 called = 2
    03 f3 called = 3
    04 f1 called = 1
    05 f4 called = 4
    06 f5 called = 5
    07 Result=7
    08 f2 called = 2
    09 f3 called = 3
    10 f1 called = 1
    11 f4 called = 4
    12 f5 called = 5
    13 inline=7
    14 Multiple side effects are undefined
    15 R1=16, i=5
    16 R2=16, j=3



    Optimisation level O1
    01 Precedence is not the same as sub-expression evaluation order
    02 f2 called = 2
    03 f3 called = 3
    04 f1 called = 1
    05 f4 called = 4
    06 f5 called = 5
    07 Result=7
    08 f2 called = 2
    09 f3 called = 3
    10 f1 called = 1
    11 f4 called = 4
    12 f5 called = 5
    13 inline=7
    14 Multiple side effects are undefined
    15 R1=16, i=5
    16 R2=16, j=3


    Optimisation level O2
    01 Precedence is not the same as sub-expression evaluation order
    02 f2 called = 2
    03 f3 called = 3
    04 f1 called = 1
    05 f4 called = 4
    06 f5 called = 5
    07 Result=7
    08 f2 called = 2
    09 f3 called = 3
    10 f1 called = 1
    11 f4 called = 4
    12 f5 called = 5
    13 inline=7
    14 Multiple side effects are undefined
    15 R1=16, i=5
    16 R2=16, j=3



    Not a lot of surprises here. The result is consistent across all three compilations and the function call order reflects what one would expect from looking at the code.


    Digital Mars Compiler Version 8.42n
    No Optimisation
    01 Precedence is not the same as sub-expression evaluation order
    02 f1 called = 1
    03 f2 called = 2
    04 f3 called = 3
    05 f4 called = 4
    06 f5 called = 5
    07 Result=7
    08 f1 called = 1
    09 f2 called = 2
    10 f3 called = 3
    11 f4 called = 4
    12 f5 called = 5
    13 inline=7
    14 Multiple side effects are undefined
    15 R1=16, i=5
    16 R2=16, j=3


    Optimisation level O1
    01 Precedence is not the same as sub-expression evaluation order
    02 f1 called = 1
    03 f2 called = 2
    04 f3 called = 3
    05 f4 called = 4
    06 f5 called = 5
    07 Result=7
    08 f1 called = 1
    09 f2 called = 2
    10 f3 called = 3
    11 f4 called = 4
    12 f5 called = 5
    13 inline=7
    14 Multiple side effects are undefined
    15 R1=16, i=5
    16 R2=16, j=3


    Optimisation level O2
    01 Precedence is not the same as sub-expression evaluation order
    02 f1 called = 1
    03 f2 called = 2
    04 f3 called = 3
    05 f4 called = 4
    06 f5 called = 5
    07 Result=7
    08 f1 called = 1
    09 f2 called = 2
    10 f3 called = 3
    11 f4 called = 4
    12 f5 called = 5
    13 inline=7
    14 Multiple side effects are undefined
    15 R1=16, i=5
    16 R2=16, j=3



    A good level of consistency, but now the order is essentially L->R as the code is read.


    gcc (GCC) 4.2.4 (Ubuntu 4.2.4-1ubuntu4)
    No Optimisation
    01 Precedence is not the same as sub-expression evaluation order
    02 f1 called = 1
    03 f2 called = 2
    04 f3 called = 3
    05 f4 called = 4
    06 f5 called = 5
    07 Result=7
    08 f1 called = 1
    09 f2 called = 2
    10 f3 called = 3
    11 f4 called = 4
    12 f5 called = 5
    13 inline=7
    14 Multiple side effects are undefined
    15 R1=16, i=5
    16 R2=16, j=5


    Optimisation level O2
    01 Precedence is not the same as sub-expression evaluation order
    02 f1 called = 1
    03 f2 called = 2
    04 f3 called = 3
    05 f4 called = 4
    06 f5 called = 5
    07 Result=7
    08 f1 called = 1
    09 f2 called = 2
    10 f3 called = 3
    11 f4 called = 4
    12 f5 called = 5
    13 inline=7
    14 Multiple side effects are undefined
    15 R1=16, i=5
    16 R2=16, j=5



    Like DMC, GCC evaluates left to right (in this test).
    But the side-effect ridden evaluation of j now results in 5 and not 3.


    lcc-win32 version 3.8. Compilation date: Mar 24 2008 11:52:21
    No Optimisation
    01 Precedence is not the same as sub-expression evaluation order
    02 f1 called = 1
    03 f2 called = 2
    04 f3 called = 3
    05 f4 called = 4
    06 f5 called = 5
    07 Result=7
    08 f1 called = 1
    09 f2 called = 2
    10 f3 called = 3
    11 f4 called = 4
    12 f5 called = 5
    13 inline=7
    14 Multiple side effects are undefined
    15 R1=16, i=5
    16 R2=16, j=3


    Optimisation enabled
    01 Precedence is not the same as sub-expression evaluation order
    02 f1 called = 1
    03 f2 called = 2
    04 f3 called = 3
    05 f4 called = 4
    06 f5 called = 5
    07 Result=7
    08 f1 called = 1
    09 f2 called = 2
    10 f3 called = 3
    11 f4 called = 4
    12 f5 called = 5
    13 inline=7
    14 Multiple side effects are undefined
    15 R1=16, i=5
    16 R2=16, j=3



    No great surprise here.


    VC6 - Microsoft 32-bit C/C++ Optimizing Compiler Version 12.00.8804
    No Optimisation
    01 Precedence is not the same as sub-expression evaluation order
    02 f1 called = 1
    03 f2 called = 2
    04 f3 called = 3
    05 f4 called = 4
    06 f5 called = 5
    07 Result=7
    08 f1 called = 1
    09 f2 called = 2
    10 f3 called = 3
    11 f4 called = 4
    12 f5 called = 5
    13 inline=7
    14 Multiple side effects are undefined
    15 R1=16, i=5
    16 R2=16, j=3


    Optimisation level O1
    01 Precedence is not the same as sub-expression evaluation order
    02 f5 called = 5
    03 f4 called = 4
    04 f3 called = 3
    05 f2 called = 2
    06 f1 called = 1
    07 Result=7
    08 f5 called = 5
    09 f4 called = 4
    10 f3 called = 3
    11 f2 called = 2
    12 f1 called = 1
    13 inline=7
    14 Multiple side effects are undefined
    15 R1=16, i=5
    16 R2=16, j=5


    Optimisation level O2
    01 Precedence is not the same as sub-expression evaluation order
    02 f5 called = 5
    03 f4 called = 4
    04 f3 called = 3
    05 f2 called = 2
    06 f1 called = 1
    07 Result=7
    08 f5 called = 5
    09 f4 called = 4
    10 f3 called = 3
    11 f2 called = 2
    12 f1 called = 1
    13 inline=7
    14 Multiple side effects are undefined
    15 R1=16, i=5
    16 R2=16, j=5



    Totally crazy!
    Turning on the optimiser calls the functions in the REVERSE order.
    And the grossly undefined evaluation of j in test2 returns a different answer to the unoptimised code.
    Is the compiler broke? Nope, the code is just rubbish.


    VS2008 - Microsoft 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08
    No Optimisation
    01 Precedence is not the same as sub-expression evaluation order
    02 f1 called = 1
    03 f2 called = 2
    04 f3 called = 3
    05 f4 called = 4
    06 f5 called = 5
    07 Result=7
    08 f1 called = 1
    09 f2 called = 2
    10 f3 called = 3
    11 f4 called = 4
    12 f5 called = 5
    13 inline=7
    14 Multiple side effects are undefined
    15 R1=16, i=5
    16 R2=16, j=4


    Optimisation level O1
    01 Precedence is not the same as sub-expression evaluation order
    02 f4 called = 4
    03 f5 called = 5
    04 f2 called = 2
    05 f3 called = 3
    06 f1 called = 1
    07 Result=7
    08 f4 called = 4
    09 f5 called = 5
    10 f2 called = 2
    11 f3 called = 3
    12 f1 called = 1
    13 inline=7
    14 Multiple side effects are undefined
    15 R1=16, i=5
    16 R2=16, j=4


    Optimisation level O2
    01 Precedence is not the same as sub-expression evaluation order
    02 f1 called = 1
    03 f2 called = 2
    04 f3 called = 3
    05 f4 called = 4
    06 f5 called = 5
    07 Result=7
    08 f1 called = 1
    09 f2 called = 2
    10 f3 called = 3
    11 f4 called = 4
    12 f5 called = 5
    13 inline=7
    14 Multiple side effects are undefined
    15 R1=16, i=5
    16 R2=16, j=4


    Now we're cooking!
    Imagine if you had code like this, and you upgraded your compiler from VC6 to VS2008.
    Not only do you get a different order of function calls when turning on optimisation, the order is no longer the same between optimisation levels!.
    And let's give a big hand to the appearance of j=4 for the first time in our results.


    Open Watcom C/C++ CL Clone for 386 Version 1.7
    No Optimisation
    01 Precedence is not the same as sub-expression evaluation order
    02 f2 called = 2
    03 f3 called = 3
    04 f1 called = 1
    05 f4 called = 4
    06 f5 called = 5
    07 Result=7
    08 f2 called = 2
    09 f3 called = 3
    10 f1 called = 1
    11 f4 called = 4
    12 f5 called = 5
    13 inline=7
    14 Multiple side effects are undefined
    15 R1=20, i=5
    16 R2=20, j=3


    Optimisation level O1
    01 Precedence is not the same as sub-expression evaluation order
    02 f2 called = 2
    03 f3 called = 3
    04 f1 called = 1
    05 f4 called = 4
    06 f5 called = 5
    07 Result=7
    08 f2 called = 2
    09 f3 called = 3
    10 f1 called = 1
    11 f4 called = 4
    12 f5 called = 5
    13 inline=7
    14 Multiple side effects are undefined
    15 R1=20, i=5
    16 R2=20, j=3


    Optimisation level O2
    01 Precedence is not the same as sub-expression evaluation order
    02 f2 called = 2
    03 f3 called = 3
    04 f1 called = 1
    05 f4 called = 4
    06 f5 called = 5
    07 Result=7
    08 f2 called = 2
    09 f3 called = 3
    10 f1 called = 1
    11 f4 called = 4
    12 f5 called = 5
    13 inline=7
    14 Multiple side effects are undefined
    15 R1=20, i=5
    16 R2=20, j=3


    More variation - where will it stop?
    The functions are back to being called in what seems to be precedence order.
    But wait, R1=R2=20
    Everything else up to now has been R1=R2=16

    Comments on this post

    • Lux Perpetua agrees : Excellent post!
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  4. #3
  5. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    but i am unable to identify whats going on in this program .
    In order to see that, you would need to read the assembly code that the compiler generates. Compilers are required to produce consistent results in accordance with the language specification, but the details of what code the compilers produce are up to the compiler. What you are attempting bypasses the specification, which causes those differences in how the compiler works to produce different outputs.

    So the short answer is Sequence point:
    A sequence point defines any point in a computer program's execution at which it is guaranteed that all side effects of previous evaluations will have been performed, and no side effects from subsequent evaluations have yet been performed. They are often mentioned in reference to C and C++, because the result of some expressions can depend on the order of evaluation of their subexpressions. Adding one or more sequence points is one method of ensuring a consistent result, because this restricts the possible orders of evaluation.
    In Java class, we were presented with a similar problem. Here is my analysis of it: Evaluating (x + x * ++x). I did a survey of how different C-like languages (including a few different C compilers in different operating systems) evaluated that expression, as well as examining the assembly listing from the C program, which revealed what was happening.
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2012
    Posts
    1
    Rep Power
    0

    Gowebbaby


    Originally Posted by vicky devshed
    void main()
    {
    int y,x=5;
    y=++x + ++x;
    printf("%d\n",x);
    printf("%d",y);
    getch();
    }


    hai guys ... please look at the above simple code , where i declared a variable named x and assigned it with a value 5 . my question here is in the expression part . ( Y=++x + ++x ) ... after executing the program i got the output as

    output
    --------
    7
    14 ..

    but i am unable to identify whats going on in this program . please make it clear to me . thanks in advance ..
    I will explain you..
    we all know prefix operator ++X = first increment the value by 1 then read x.
    post fix operator x++=first read the increment.

    your Q is y=++X + ++X

    x=5

    ++X=1+5=6

    again ++X= 1+6=7

    simply the last value of x is 7
    so when you print x the it return the value 7

    finnaly value of y= 7+7=14.
    thats it.

    Comments on this post

    • salem disagrees : completely wrong and clueless
    • b49P23TIvg disagrees : Please read all of post 2 this thread.
  8. #5
  9. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,841
    Rep Power
    480
    peterjohnsongwb, you jumped into the pit!
    Originally Posted by salem
    test2() is just broken code with no redeeming features. Yet despite this, people often claim they know how the result is worked out.
    Last edited by b49P23TIvg; July 30th, 2012 at 09:05 AM. Reason: unclear
    [code]Code tags[/code] are essential for python code and Makefiles!
  10. #6
  11. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    peterjohnsongwb, you poor clueless fool. The answer depends entirely on how the compiler-generated code handles that expression.

    y = ++x + ++x;

    By hand, the answer should be 13 (6 + 7).

    With C, the answer is 14.
    With Java, the answer is the expected one, 13.

    Both languages should yield the same result, but they don't.

    C generates native code, while Java runs a virtual machine (VM), a fictional computer that it emulates on whatever physical computer it happens to be running on (like Pascal's p-code approach, only this one actually caught on). C code will handle memory access within expression evaluation in whatever manner that particular machine dictates, be it direct RAM access or stack-oriented evaluation. On all machines, Java will evaluate expressions on a stack as per the VM specification.

    Because my C compiler (MinGW gcc) modifies x directly in memory -- you can and should verify this in the assembly listing, which is the only way to really tell what's going on -- , the first term of the expression ends up having been pre-incremented twice instead of only once, thus producing a bogus result. It does not matter exactly how that particular bogus result was produced; it's still bogus!

    The lesson is not why that happened (unless this is an advanced computer science class whose purpose is to investigate bogus compiler-generated code), but rather that writing such expressions is stupid and must be avoided!
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2012
    Posts
    3
    Rep Power
    0
    Originally Posted by dwise1_aol
    peterjohnsongwb, you poor clueless fool. The answer depends entirely on how the compiler-generated code handles that expression.

    y = ++x + ++x;

    By hand, the answer should be 13 (6 + 7).

    With C, the answer is 14.
    With Java, the answer is the expected one, 13.

    Both languages should yield the same result, but they don't.

    C generates native code, while Java runs a virtual machine (VM), a fictional computer that it emulates on whatever physical computer it happens to be running on (like Pascal's p-code approach, only this one actually caught on). C code will handle memory access within expression evaluation in whatever manner that particular machine dictates, be it direct RAM access or stack-oriented evaluation. On all machines, Java will evaluate expressions on a stack as per the VM specification.

    Because my C compiler (MinGW gcc) modifies x directly in memory -- you can and should verify this in the assembly listing, which is the only way to really tell what's going on -- , the first term of the expression ends up having been pre-incremented twice instead of only once, thus producing a bogus result. It does not matter exactly how that particular bogus result was produced; it's still bogus!

    The lesson is not why that happened (unless this is an advanced computer science class whose purpose is to investigate bogus compiler-generated code), but rather that writing such expressions is stupid and must be avoided!


    thanks for your reply dwise1_aol ... but , please dont mistake me. because i am a beginner in cprogramming and i dont even know how to program .. this is my first try , and that question may seem to be crazy .. but i got the output as such ( 7,14 ) .
    thats why i raised this question..
    you quoted like

    "but rather that writing such expressions is stupid and must be avoided " ..

    why are you saying so .. ??
  14. #8
  15. I'm Baaaaaaack!
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    Jul 2003
    Location
    Maryland
    Posts
    5,538
    Rep Power
    244
    As has been explained, you are invoking undefined behavior. The results of undefined behavior are, rather ironically, _undefined_, so there is no way to predict it.

    Don't write code that behaves in an undefined way!

    My blog, The Fount of Useless Information http://sol-biotech.com/wordpress/
    Free code: http://sol-biotech.com/code/.
    Secure Programming: http://sol-biotech.com/code/SecProgFAQ.html.
    Performance Programming: http://sol-biotech.com/code/PerformanceProgramming.html.
    LinkedIn Profile: http://www.linkedin.com/in/keithoxenrider

    It is not that old programmers are any smarter or code better, it is just that they have made the same stupid mistake so many times that it is second nature to fix it.
    --Me, I just made it up

    The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man.
    --George Bernard Shaw
  16. #9
  17. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    > but i got the output as such ( 7,14 ) .
    And if you try some other compilers (like I did), you'll get some different answers.

    Good code should produce the SAME answer on all compilers. Now, if we discount that there could be a bug in multiple production compilers for such simple code, then we're left with either the code is buggy, or it has undefined behaviour (UB) in it.

    Whilst experimentation is good, you can't learn the language from simply observing effects on one single compiler and assuming that everyone else does the same thing. If you want to learn what is really allowed, then you also need to read the language specification(s) as well ( clicky )

    If you learn C to the limits defined by the standard, then all the issues which newbies have when switching compilers just go away.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  18. #10
  19. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    Refer again to Msg#3 by me.

    Pay especial attention to the term sequence point. In Msg#3, that is a link to the Wikipedia article on sequence points. Read it!
  20. #11
  21. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2012
    Location
    India, cochin
    Posts
    1
    Rep Power
    0
    dwise1_aol great answer...
  22. #12
  23. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2012
    Posts
    7
    Rep Power
    0
    I agree with my friend peterjohnsongwb. he explains very clearly step by step.
  24. #13
  25. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    > I agree with my friend peterjohnsongwb. he explains very clearly step by step.
    Then you're just as ignorant and deluded as well.
    Just read my long post - which answer is "correct"?

    Simply coming up with an explanation of a single result (for one example code, written for one compiler) is NOT the same as explaining how EVERY compiler deals with ANY code.

    Here's a special place, just for you

    Comments on this post

    • mitakeet agrees : A new term for me! Thanks!
    • ptr2void agrees : But I'm quite sure the *wrong* answer is the one the Indian or Filipino tutor wants.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  26. #14
  27. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    Originally Posted by quino
    I agree with my friend peterjohnsongwb. he explains very clearly step by step.
    Code that produces the wrong output continues to produce the wrong output regardless of how well you can explain what it did to produce that wrong output.

    The goal is to write code that produces correct output. The only valid purpose for trying to understand exactly how code had produced wrong output is to enable you to correct the code. Your "friend" did not in any way offer any insight into how to correct the code, hence his input was worthless.

    Always remember your goals.

IMN logo majestic logo threadwatch logo seochat tools logo