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

    Join Date
    May 2010
    Posts
    6
    Rep Power
    0

    Lightbulb Problem with increment operator in C/C++


    Can anyone please explain me the following results?

    int y,x;
    x=4;
    y=x+ ++x + ++x;
    printf("%d",y);


    The output comes out to be 16. How?
    :chomp: :chomp: :chomp: :chomp:
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Oct 2007
    Posts
    921
    Rep Power
    536
    The line
    Code:
      y = x+++x+++x;
    is modifying x more than once. The results of that are undefined - a compiler is allowed to produce any result it likes.

    Incidentally, adding space characters does not change the meaning and the way you have placed the spaces in your code does not represent how the compiler scans that line. The C scanner is always greedy.
    Right 98% of the time, and don't care about the other 3%.

    It has been said that the great scientific disciplines are examples of giants standing on the shoulders of other giants. It has also been said that the software industry is an example of midgets standing on the toes of other midgets. (Alan Cooper)
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2010
    Posts
    6
    Rep Power
    0
    Are u sure abt that?
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2010
    Posts
    6
    Rep Power
    0
    y=x+++x+++x can be interpreted by the compiler in the following ways-

    y=(x++)+(x++)+x;
    or
    y=(x++)+x+(++x);
    or
    y=(x)+(++x)+(++X);

    None of the above will come out to be 16 (x=4).
    What would you like to say to that?
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Oct 2007
    Posts
    921
    Rep Power
    536
    +ve. Undefined means the compiler can do what it likes, including doing each increment in parallel pipelines. in reverse order, or anything else.

    Also, try to use reasonable english expression here rather than SMS-style laziness.
    Last edited by LittleGrin; May 31st, 2010 at 04:32 AM.
    Right 98% of the time, and don't care about the other 3%.

    It has been said that the great scientific disciplines are examples of giants standing on the shoulders of other giants. It has also been said that the software industry is an example of midgets standing on the toes of other midgets. (Alan Cooper)
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2010
    Posts
    6
    Rep Power
    0
    Thanks a lot.
    And I will keep in mind not to use the SMS-style language here :)
  12. #7
  13. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,392
    Rep Power
    1871
    Read this, it's all about expressions, side effects, and sequence points.

    > None of the above will come out to be 16 (x=4).
    > What would you like to say to that?
    You getting 16 is easy to explain.

    > x=4;
    > y=x+ ++x + ++x;

    Red happens first, incrementing x to 5
    Blue happens, and 5 is added to 5 (result is 10)
    Magenta increments x to 6
    6 is added to 10, and the answer is 16.


    What you're NOT going to get is 16 on EVERY single compiler (past, present or future). Figuring out how such expressions are evaluated is a fun party trick, but it isn't any information you could use to write a good program with.
    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
  14. #8
  15. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,392
    Rep Power
    1871
    Why even bother, when it's spammed over the net :(

    Comments on this post

    • Yawmark agrees
    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
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2010
    Posts
    6
    Rep Power
    0
    "Red happens first, incrementing x to 5
    Blue happens, and 5 is added to 5 (result is 10)
    Magenta increments x to 6
    6 is added to 10, and the answer is 16."


    I think Blue cannot happen second as per the precedence rules of C. The "++" operator has higher priority than "+" operator, isn't it?

    Comments on this post

    • DaWei_M disagrees : It doesn't matter. It's undefined. If you post on multiple forums, at least tell us so we don't unnecessarily waste time explaining things to a rude doink.
  18. #10
  19. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,172
    Rep Power
    2222
    Do not even begin to try to analyze what's going on until you have studied the assembly listing for that expression. Without understanding that assembly code, you have absolutely no idea what's happening under the hood!

    While still ignorant of the assembly code that the compiler generated, you are reduced to just making wild guesses. Why waste your time with wild guesses?


    I think Blue cannot happen second as per the precedence rules of C. The "++" operator has higher priority than "+" operator, isn't it?
    Assembly code trumps the precedence rules. True, the compiler will apply the precedence rules in attempting to generate the proper sequence of operations, but the other functionality of the code will come into effect, such as saving intermediate values.

    Many years ago in Java class, the teacher presented this snippet of code and asked us for the value of y:
    Code:
        x = 3;
        y = x + x * ++x;
        System.out.println("x = "+x+"; x + x * ++x = "+y+"\n");
    Drawing on my computer science background, I converted that infix expression to postfix and evaluated it on a stack and found that y was 15, which is what the program displayed when it was run. But the instructor expected the answer to be 20.

    During the next week, I ran that same code (modified as needed, of course) in a variety of C-like languages as well as with a number of different C compilers. Most of them gave the answer of 20, whereas a few (Java, JavaScript, and PocketC, a small C compiler for the Palm Pilot PDA) gave 15.

    I then generated an assembly listing from the Visual C++ test and found the reason. Because Java and JavaScript must execute the same on any platform, they are specified to use stack evaluation (I know that for Java, having read its VM specification, and am assuming that same for JavaScript). However, Intel code normally does not use a stack for expression evaluation, but rather stores memory locations. Particularly in the case of increment/decrement, the variable value is changed immediately.

    For that expression:
    y = x + x * ++x;
    the C compiler generated this code:
    Code:
    ; y = fffc
    ; x = fffa
    ;     volatile int x;
    ; Line 6
    ;     int y;
    ; Line 7
    ;             
    ;     x = 3;            
    ; Line 9
        *** 00000d  c7 46 fa 03 00      mov WORD PTR -6[bp],OFFSET 3
    ;     y = x + x * ++x;
    ; Line 10
        *** 000012  83 46 fa 01         add WORD PTR -6[bp],OFFSET 1
        *** 000016  8b 46 fa        mov ax,WORD PTR -6[bp]
        *** 000019  f7 6e fa        imul    WORD PTR -6[bp]
        *** 00001c  03 46 fa        add ax,WORD PTR -6[bp]
        *** 00001f  89 46 fc        mov WORD PTR -4[bp],ax
    As you can see, the first operation performed was the ++x, which changed the value of x from 3 to 4. Then since each subsequent operation read that incremented value of x directly from its memory location. So, instead of evaluating 3 + 3 * 4 = 15 as we would expect by reading the source code, the C program instead evaluated 4 + 4 * 4 = 20. Different results despite using the exact same order of precedence.

    So in cases such as this, until you know what the code is actually doing, you're just wandering around lost, making nothing but wild guesses.

    Comments on this post

    • Yawmark agrees
    Last edited by dwise1_aol; May 31st, 2010 at 12:57 PM.
  20. #11
  21. Feelin' Groovy
    Devshed Supreme Being (6500+ posts)

    Join Date
    Aug 2001
    Location
    WDSMIA
    Posts
    10,135
    Rep Power
    5054
    Originally Posted by LittleGrin
    +ve. Undefined means the compiler can do what it likes, including doing each increment in parallel pipelines. in reverse order, or anything else.

    Also, try to use reasonable english expression here rather than SMS-style laziness.
    :rolleyes:

    ~

    Comments on this post

    • DaWei_M agrees : You realize it was intentional irony, of course. ;)
    Yawmark
    class Sig{public static void main(String...args){\u0066or(int
    \u0020$:"v\"ʲ\"vΤ\"".to\u0043h\u0061rArray()
    )System./*goto/*$/%\u0126//^\u002A\u002Fout.print((char)(($>>
    +(~'"'&'#'))+('<'>>('\\'/'.')/\u002Array.const(~1)\*\u002F)));}}

IMN logo majestic logo threadwatch logo seochat tools logo