Thread: Side_effect: (++x + y*x + y*x) != (y*x + ++x + y*x) ?

  1. #1
    Registered User
    Join Date
    Apr 2002
    Posts
    6

    Question Side_effect: (++x + y*x + y*x) != (y*x + ++x + y*x) ?

    Hello everybody,
    I have met many problem with C because of side-affect but until now I couldn't handle them yet.
    I have a code segment that:
    x=2; y= 2;
    printf("%d\n", ++x + y*x + y*x); // result:11 ?
    x=2; y= 2;
    printf("%d\n", y*x + ++x + y*x); // result:13 ?

    And another segment:
    int x=24, y=20, z=90, result;
    kq = ++x + y*(z -x);
    printf("%d", kq);

    outputs the result difference from the code below:
    int x=24, y=20, z=90, result;
    printf("%d", ++x + y*(z -x));

    And many problem that follow with the ++, -- operator.
    Who know how to handle these problem or any site that mentions about these, please help me.

    Thanks for your kindness.

  2. #2
    Me want cookie! Monster's Avatar
    Join Date
    Dec 2001
    Posts
    680
    Sorry, but I don't see a problem. You are using ++x, this means first increment x and then evaluate the expression.

  3. #3
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    x=2; y= 2;
    printf("%d\n", ++x + y*x + y*x); // result:11 ?
    x=2; y= 2;
    printf("%d\n", y*x + ++x + y*x); // result:13 ?
    The first expression should print 15 and the second 13. Why?

    z = 0
    z = 2 + 1, z = 3
    z += 3 * 2, z = 9
    z += 3 * 2, z = 15

    z = 0
    z += 2 * 2, z = 4
    z += 2 + 1, z = 7
    z += 3 * 2, z = 13

    How the expression is evaluated depends on where you increment x. Having fun yet?

    >And another segment:
    I get the same result for both.

    >Who know how to handle these problem or any site that mentions about these
    Understand exactly where you are changing values and how the computer does it, then just use parens to make sure it works how you want it to.

    -Prelude
    My best code is written with the delete key.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    Quite simply, all those code snippets are junk
    http://www.eskimo.com/~scs/C-faq/q3.2.html

    If you have an expression containing the same variable used in two different places, and either (or both) of them have a side effect (++,--), then the expression is undefined - period. No if, buts or maybes about it.

    > How the expression is evaluated depends on where you increment x.
    Except it doesn't (see above FAQ)
    You only know that x will be incremented before the next sequence point - you can never know when this will be in relation to your other uses of x in the same expression.
    I've seen similar code, when compiled using optimisation, produce different results from the unoptimised code.

    > Who know how to handle these problem or any site that mentions about these
    You write better code which doesn't have undefined behaviour.

    > then just use parens to make sure it works how you want it to
    Sadly, this doesn't work either.

  5. #5
    Unregistered
    Guest
    Originally posted by Monster
    z = 0
    z = 2 + 1, z = 3
    z += 3 * 2, z = 9
    z += 3 * 2, z = 15

    z = 0
    z += 2 * 2, z = 4
    z += 2 + 1, z = 7
    z += 3 * 2, z = 13
    I don't think the result is as your eplaination.
    If you assign those expressions for two variables as follow:
    x=2; y=3;
    kq = ++x + y*x + y*x; ==> kq = 3 + 3*3 + 3*3 = 21
    x=2; y=3;
    kq = y*x + ++x + y*x; ==> kq = 3*3 + 3 + 3*3 = 21
    Two result is equal (=21)

    The problem is when you put these expressin into the printf function. The result is exactly what I wrote.

    According to C rule, when in the expression has the ++x operator, the value of x will increate by 1 and this operator will be execute first, evenif you put it at the end of expression.

    The strange that I want to share with you is the differences between from two result of expressions when you put the expression out of the printf and in the printf. For ex (x=2, y=3):

    kq = ++x + y*x + y*x; // ==> kq = 21
    kq = y*x + y*x + ++x; // ==> kq = 21
    ....
    but:
    printf("%d", ++x + y*x + y*x); // ==> 15
    printf("%d", y*x + ++x + y*x); // ==> 18
    printf("%d", y*x + y*x + ++x); // ==> 18

    That is the problem and I can't understand the way that Borland C compiler evalues an expression in printf function.

    Thanks for your help.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    < That is the problem and I can't understand the way that Borland C compiler evalues an expression in printf function.
    Didn't you read the FAQ I posted?

    Expressions like this are meaningless

    Attempting to understand them is pointless

    Even if you figure out all the rules for your compiler, it wont do you any good because every other compiler will be different.

  7. #7
    Registered User
    Join Date
    Apr 2002
    Posts
    6

    Smile

    Hi Salem,
    Thanks for your advise.
    I also think like you but I have face with the situation that requires me have to understand this problem. That is in my exam, there is a question:
    Q: The output of following expression (x=2; y=3; z=5
    ++x + y*(z - x)
    I anwsered the result is 3 + 3*(5-3) = 9
    but the solution is 12 because my teacher used:
    printf("%d", ++x+y*(z-x)); //==> result is 3+3*(5-2) ???
    while I used:
    kq = ++x + y*(z-x);
    printf("%d", kq); //==> result is 3+3*(5-3)

    I discover this problem when my test's grade is low than I've hoped and I don't know that who is right.
    That is the reason I want to hanlde this problem.

    Thank for your kindness.

  8. #8
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    Well, like Salem said, the question is really invalid if the results are undefined. But for the record, I compiled and ran this code on Borland 5.5 and gcc 2.95, and they both came to the answer 9.
    Code:
    #include <stdio.h>
    int main(void)
    {
    	int x=2, y=3, z=5;
    	printf("%d\n", ++x + y*(z - x) );
    	return(0);
    }
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    > that requires me have to understand this problem
    Then you're in the wrong place - you're learning C from someone who doesn't have a clue about side effects.

    > because my teacher used
    Is an ignorant fool!
    How much more brain damage(1) are you going to learn from them?
    What are you going to do when one (or more) of their "gospel truths" turns out to be false in the real world?

    Having seen the number of mistakes that all these "teachers" have made in the past, I'm not impressed.

    > I anwsered the result is 3 + 3*(5-3) = 9
    Is one plausable answer.

    > but the solution is 12 because my teacher used
    Is another plausable answer, which is no more correct than yours. The only thing wrong here is your teacher claiming authority, and deciding that their answer is right, and yours is wrong.

    Your real problem is figuring out how your teacher has got all the rules wrong, then asks you to answer questions with no correct answer, then out of spite knocks your grade down.

    Better yet, find out which compiler (and version) they use, and perhaps we can craft a trap for them

    Feel free to direct them to this site or the comp.lang.c FAQ

    > I don't know that who is right
    Between who - you and your teacher?
    At the moment, my money is on you - at least you have the sense to question the apparent answer.

    By the way, no one writes code like that in the real world - it is (at best) a cheap shot to make the newbies awkward.

  10. #10
    Registered User
    Join Date
    May 2002
    Posts
    1
    Originally posted by Unregistered


    I don't think the result is as your eplaination.
    If you assign those expressions for two variables as follow:
    x=2; y=3;
    kq = ++x + y*x + y*x; ==> kq = 3 + 3*3 + 3*3 = 21
    x=2; y=3;
    kq = y*x + ++x + y*x; ==> kq = 3*3 + 3 + 3*3 = 21
    Two result is equal (=21)

    The problem is when you put these expressin into the printf function. The result is exactly what I wrote.

    According to C rule, when in the expression has the ++x operator, the value of x will increate by 1 and this operator will be execute first, evenif you put it at the end of expression.

    The strange that I want to share with you is the differences between from two result of expressions when you put the expression out of the printf and in the printf. For ex (x=2, y=3):

    kq = ++x + y*x + y*x; // ==> kq = 21
    kq = y*x + y*x + ++x; // ==> kq = 21
    ....
    but:
    printf("%d", ++x + y*x + y*x); // ==> 15
    printf("%d", y*x + ++x + y*x); // ==> 18
    printf("%d", y*x + y*x + ++x); // ==> 18

    That is the problem and I can't understand the way that Borland C compiler evalues an expression in printf function.

    Thanks for your help.


    --------------------------

    It evaluates from right to left.

  11. #11
    Registered User
    Join Date
    Apr 2002
    Posts
    6
    Originally posted by Salem
    >> because my teacher used
    Is an ignorant fool!
    How much more brain damage cheap shot to make the newbies awkward.
    Thanks for your advises very much.
    I agree with you that we shouldn't pay attention to these useless points. But I think that when we face an unusual problem, we shouldn't discover it as much as posible. That is my point of view.
    I don't want to study these problems but when I met them, I want to discover them. Don't you recognize that these problems are also interesting? When we learn C language, we know that the ++ operator much be excuted first but in printf function why does it evalute such result?
    Until now, I also really want to know these problem, not for my grade, not for studying C language but only for my doubt.

    By the way, I have some relay to Hammer that you don't understand my idea. I don't wonder about the result of one of the statement but the difference between the value of expression in printf function and in the assignment statement.

    Thanks.

  12. #12
    Registered User
    Join Date
    Apr 2002
    Posts
    6
    Originally posted by float29

    It evaluates from right to left.
    I don't think so. If it evaluates from right to left, result of the third expression is 21, not 18.
    printf("%d", ++x + y*x + y*x); // ==> 15
    printf("%d", y*x + ++x + y*x); // ==> 18
    printf("%d", y*x + y*x + ++x); // ==> 18 (21 insteads as your rule)
    Do you agree with me ?
    Last edited by Trancongan; 05-06-2002 at 09:29 AM.

  13. #13
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >It evaluates from right to left.
    Evaluation is undefined. If any part of an expression is undefined then the *entire* expression is undefined.

    -Prelude
    My best code is written with the delete key.

  14. #14
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    >Don't you recognize that these problems are also interesting?
    No - undefined operations are not interesting, because there is nothing useful you can do with whatever answer you 'think' you might know as a result.

    > but the difference between the value of expression in printf function and in the assignment statement.
    Congratulations - you've actually seen what undefined actually means - now move on.

    > we know that the ++ operator much be excuted first
    Except that you don't

    Consider
    a = b + c * d;
    The only thing you know for sure is that * will be applied before +, because that is encoded in the precedence rules (and that is all you can say about this expression).

    For example, you don't know whether the compiler copies all of those values into registers in b,c,d order, or even d,c,b order or whether it's just c and d (or d,c) or anything else. So long as the answer is consistent with the rules of arithmetic, you shouldn't give a damn what order operands of the expression are evaluated in.

    Now apply that to
    a = ++b + b;
    Which b is loaded into a register (ie evaluated) first - left or right?
    Answer - you don't know (for sure).
    The language does not specify such an order, because it should not matter to your code. It's only when you invoke undefined behaviour that you glimpse what is going on, but like I've said before, this is of no use to you.

    Sure, when the left hand b is evaluated, it is incremented and then loaded. But what about the right one - if its already in a register, then ALL your assumptions are broken.

    > ++x + y*x + y*x
    Now this - how many registers does your machine have?
    Given any sufficiently complex expression, you will run out, and then the compiler is working in a different way with partial sub-expressions.

  15. #15
    Registered User
    Join Date
    Apr 2002
    Posts
    6
    > a = ++b + b;
    > Which b is loaded into a register (ie evaluated) first - left or right?
    >Answer - you don't know (for sure).

    Sorry Salem,
    Maybe I don't have much experiences in C language as you but I have enough knowledge to sure that the order of the execute of this expression.

    Another idea that the key of this problem - the difference between of value in printf function and out of the printf function - is not in the way compiler place value of variable into register.

    As we've learnt, if we place an expression in a printf function, the expression will be evalue first and return value of the expression will be used for this function.
    If the key is at register as you said, we have the same result in both expression - in and out of the printf function. Do you agree with me?

    Until now, my doubt is also that why there is the difference of evaluetion an expression in and out the printf function.

    Thanks all.

Popular pages Recent additions subscribe to a feed