Thread: Post and Pre Increment

  1. #1
    Registered User Raj 89's Avatar
    Join Date
    Nov 2012
    Location
    Chennai, TamilNadu
    Posts
    16

    Post and Pre Increment

    Hi All,

    Please help me in this.

    Code:
    #include <stdio.h>
    
    int main(void )
    {
    int i = 1 ;
    printf("\n%d %d %d %d\n\n",i++,++i,++i,i++) ;
    return 0 ;
    }
    I am using Mandriva linux and i am using a gcc compiler. In the above mentioned code i am facing a great trouble in finding the reason for result.

    The output that i am supposed to get is 1 3 4 4

    But i a different ouput that not even matches with these...

    Please help me in these...


  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > The output that i am supposed to get is 1 3 4 4
    There is no "supposed" to about it.
    The code is broken, so all answers are equally wrong.



    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

    Precedence is not the same as sub-expression evaluation order
    f2 called = 2
    f3 called = 3
    f1 called = 1
    f4 called = 4
    f5 called = 5
    Result=7
    f2 called = 2
    f3 called = 3
    f1 called = 1
    f4 called = 4
    f5 called = 5
    inline=7
    Multiple side effects are undefined
    R1=16, i=5
    R2=16, j=3



    Optimisation level O1

    Precedence is not the same as sub-expression evaluation order
    f2 called = 2
    f3 called = 3
    f1 called = 1
    f4 called = 4
    f5 called = 5
    Result=7
    f2 called = 2
    f3 called = 3
    f1 called = 1
    f4 called = 4
    f5 called = 5
    inline=7
    Multiple side effects are undefined
    R1=16, i=5
    R2=16, j=3


    Optimisation level O2

    Precedence is not the same as sub-expression evaluation order
    f2 called = 2
    f3 called = 3
    f1 called = 1
    f4 called = 4
    f5 called = 5
    Result=7
    f2 called = 2
    f3 called = 3
    f1 called = 1
    f4 called = 4
    f5 called = 5
    inline=7
    Multiple side effects are undefined
    R1=16, i=5
    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

    Precedence is not the same as sub-expression evaluation order
    f1 called = 1
    f2 called = 2
    f3 called = 3
    f4 called = 4
    f5 called = 5
    Result=7
    f1 called = 1
    f2 called = 2
    f3 called = 3
    f4 called = 4
    f5 called = 5
    inline=7
    Multiple side effects are undefined
    R1=16, i=5
    R2=16, j=3


    Optimisation level O1

    Precedence is not the same as sub-expression evaluation order
    f1 called = 1
    f2 called = 2
    f3 called = 3
    f4 called = 4
    f5 called = 5
    Result=7
    f1 called = 1
    f2 called = 2
    f3 called = 3
    f4 called = 4
    f5 called = 5
    inline=7
    Multiple side effects are undefined
    R1=16, i=5
    R2=16, j=3


    Optimisation level O2

    Precedence is not the same as sub-expression evaluation order
    f1 called = 1
    f2 called = 2
    f3 called = 3
    f4 called = 4
    f5 called = 5
    Result=7
    f1 called = 1
    f2 called = 2
    f3 called = 3
    f4 called = 4
    f5 called = 5
    inline=7
    Multiple side effects are undefined
    R1=16, i=5
    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

    Precedence is not the same as sub-expression evaluation order
    f1 called = 1
    f2 called = 2
    f3 called = 3
    f4 called = 4
    f5 called = 5
    Result=7
    f1 called = 1
    f2 called = 2
    f3 called = 3
    f4 called = 4
    f5 called = 5
    inline=7
    Multiple side effects are undefined
    R1=16, i=5
    R2=16, j=5


    Optimisation level O2

    Precedence is not the same as sub-expression evaluation order
    f1 called = 1
    f2 called = 2
    f3 called = 3
    f4 called = 4
    f5 called = 5
    Result=7
    f1 called = 1
    f2 called = 2
    f3 called = 3
    f4 called = 4
    f5 called = 5
    inline=7
    Multiple side effects are undefined
    R1=16, i=5
    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

    Precedence is not the same as sub-expression evaluation order
    f1 called = 1
    f2 called = 2
    f3 called = 3
    f4 called = 4
    f5 called = 5
    Result=7
    f1 called = 1
    f2 called = 2
    f3 called = 3
    f4 called = 4
    f5 called = 5
    inline=7
    Multiple side effects are undefined
    R1=16, i=5
    R2=16, j=3


    Optimisation enabled

    Precedence is not the same as sub-expression evaluation order
    f1 called = 1
    f2 called = 2
    f3 called = 3
    f4 called = 4
    f5 called = 5
    Result=7
    f1 called = 1
    f2 called = 2
    f3 called = 3
    f4 called = 4
    f5 called = 5
    inline=7
    Multiple side effects are undefined
    R1=16, i=5
    R2=16, j=3



    No great surprise here.


    VC6 - Microsoft ® 32-bit C/C++ Optimizing Compiler Version 12.00.8804
    No Optimisation

    Precedence is not the same as sub-expression evaluation order
    f1 called = 1
    f2 called = 2
    f3 called = 3
    f4 called = 4
    f5 called = 5
    Result=7
    f1 called = 1
    f2 called = 2
    f3 called = 3
    f4 called = 4
    f5 called = 5
    inline=7
    Multiple side effects are undefined
    R1=16, i=5
    R2=16, j=3


    Optimisation level O1

    Precedence is not the same as sub-expression evaluation order
    f5 called = 5
    f4 called = 4
    f3 called = 3
    f2 called = 2
    f1 called = 1
    Result=7
    f5 called = 5
    f4 called = 4
    f3 called = 3
    f2 called = 2
    f1 called = 1
    inline=7
    Multiple side effects are undefined
    R1=16, i=5
    R2=16, j=5


    Optimisation level O2

    Precedence is not the same as sub-expression evaluation order
    f5 called = 5
    f4 called = 4
    f3 called = 3
    f2 called = 2
    f1 called = 1
    Result=7
    f5 called = 5
    f4 called = 4
    f3 called = 3
    f2 called = 2
    f1 called = 1
    inline=7
    Multiple side effects are undefined
    R1=16, i=5
    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

    Precedence is not the same as sub-expression evaluation order
    f1 called = 1
    f2 called = 2
    f3 called = 3
    f4 called = 4
    f5 called = 5
    Result=7
    f1 called = 1
    f2 called = 2
    f3 called = 3
    f4 called = 4
    f5 called = 5
    inline=7
    Multiple side effects are undefined
    R1=16, i=5
    R2=16, j=4


    Optimisation level O1

    Precedence is not the same as sub-expression evaluation order
    f4 called = 4
    f5 called = 5
    f2 called = 2
    f3 called = 3
    f1 called = 1
    Result=7
    f4 called = 4
    f5 called = 5
    f2 called = 2
    f3 called = 3
    f1 called = 1
    inline=7
    Multiple side effects are undefined
    R1=16, i=5
    R2=16, j=4


    Optimisation level O2

    Precedence is not the same as sub-expression evaluation order
    f1 called = 1
    f2 called = 2
    f3 called = 3
    f4 called = 4
    f5 called = 5
    Result=7
    f1 called = 1
    f2 called = 2
    f3 called = 3
    f4 called = 4
    f5 called = 5
    inline=7
    Multiple side effects are undefined
    R1=16, i=5
    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

    Precedence is not the same as sub-expression evaluation order
    f2 called = 2
    f3 called = 3
    f1 called = 1
    f4 called = 4
    f5 called = 5
    Result=7
    f2 called = 2
    f3 called = 3
    f1 called = 1
    f4 called = 4
    f5 called = 5
    inline=7
    Multiple side effects are undefined
    R1=20, i=5
    R2=20, j=3


    Optimisation level O1

    Precedence is not the same as sub-expression evaluation order
    f2 called = 2
    f3 called = 3
    f1 called = 1
    f4 called = 4
    f5 called = 5
    Result=7
    f2 called = 2
    f3 called = 3
    f1 called = 1
    f4 called = 4
    f5 called = 5
    inline=7
    Multiple side effects are undefined
    R1=20, i=5
    R2=20, j=3


    Optimisation level O2

    Precedence is not the same as sub-expression evaluation order
    f2 called = 2
    f3 called = 3
    f1 called = 1
    f4 called = 4
    f5 called = 5
    Result=7
    f2 called = 2
    f3 called = 3
    f1 called = 1
    f4 called = 4
    f5 called = 5
    inline=7
    Multiple side effects are undefined
    R1=20, i=5
    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
    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.

  3. #3
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    Salem's answer is right, but also you should try compiling with -Wall; it will warn you of this problem:

    gcc -Wall -o try try.c

    try.c: In function 'main':
    try.c:6:42: warning: operation on 'i' may be undefined [-Wsequence-point]
    try.c:6:42: warning: operation on 'i' may be undefined [-Wsequence-point]
    try.c:6:42: warning: operation on 'i' may be undefined [-Wsequence-point]
    Write it like this instead:

    Code:
    int main(void)
    {
        int i = 1;
        {
            int a,b,c,d;
            a=i++, b=++i, c=++i, d=i++;
            printf("\n%d %d %d %d\n\n",a,b,c,d) ;
        }
        return 0;
    }
    The comma operator with side effects is well-defined only when it appears as part of an expression (as is the case in the line before printf). It is not well-defined when it appears as part of an argument list (as is the case in printf).

  4. #4
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    945
    Quote Originally Posted by c99tutorial View Post
    The comma operator with side effects is well-defined only when it appears as part of an expression (as is the case in the line before printf). It is not well-defined when it appears as part of an argument list (as is the case in printf).
    In the context of a function call, the comma is not an operator. It is an argument list separator.

  5. #5
    Registered User Raj 89's Avatar
    Join Date
    Nov 2012
    Location
    Chennai, TamilNadu
    Posts
    16
    Quote Originally Posted by Salem View Post
    >

    - Changing compiler options changes things.
    - Changing compiler changes things.
    - Even changing the compiler version changes things!.
    In short - "DON'T GO THERE!"
    Nice... Perfect... A splendid explanation.... If so, there is a change in everything, what is the exact compiler that we can depend on?

  6. #6
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    Quote Originally Posted by Raj 89
    what is the exact compiler that we can depend on?
    You should always try to write code to run on all compilers and operating systems: It will save you a lot of grief down the track.
    Fact - Beethoven wrote his first symphony in C

  7. #7
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    945
    Quote Originally Posted by Raj 89 View Post
    Nice... Perfect... A splendid explanation.... If so, there is a change in everything, what is the exact compiler that we can depend on?
    Depend on for what? Giving you the result that you expect? What result do you expect, anyway?

    The point of Salem's post is that any result from an undefined expression, like the one you posted, is valid. You cannot depend on any compiler to give you consistent results. (If a compiler happens to give consistent results, you're just being lucky.)

  8. #8
    Registered User Raj 89's Avatar
    Join Date
    Nov 2012
    Location
    Chennai, TamilNadu
    Posts
    16
    Quote Originally Posted by christop View Post
    If a compiler happens to give consistent results, you're just being lucky.
    Well thanks christop. I m not that much luky. Well, i am trying to make myself lucky.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Post Increment an Pre Increment operators in c++
    By anil_ in forum C++ Programming
    Replies: 4
    Last Post: 11-12-2011, 08:27 PM
  2. pre & post increment need help
    By zing_foru in forum C Programming
    Replies: 6
    Last Post: 10-09-2009, 12:14 PM
  3. pre/Post Increment
    By ganesh bala in forum C Programming
    Replies: 1
    Last Post: 02-12-2009, 04:17 AM
  4. post vs pre increment
    By xddxogm3 in forum C Programming
    Replies: 13
    Last Post: 03-19-2004, 05:07 PM
  5. Post increment and pre increment help
    By noob2c in forum C++ Programming
    Replies: 5
    Last Post: 08-05-2003, 03:03 AM