operator precedence

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • arnaudk
    Contributor
    • Sep 2007
    • 425

    operator precedence

    For int a=5, why does a++ * ++a = 36 because * acts left-to-right and ++a pre-increments a so we should have 5x7=35. My books all say that ++ has precedence over *.
    Last edited by arnaudk; May 15 '08, 06:20 PM. Reason: The premise of my question was wrong...
  • Sick0Fant
    New Member
    • Feb 2008
    • 121

    #2
    Originally posted by arnaudk
    For int a=5, why does a++ * ++a = 36 because * acts left-to-right and ++a pre-increments a so we should have 5x7=35. My books all say that ++ has precedence over *.
    I'm not entirely sure, but a++ will only increment after the end of the statement, while ++a will increment a before the statement.

    So, since we have ++a in the statement, a = 6

    so a++ * ++a = 36

    and after that statement, a = 7.

    Comment

    • oler1s
      Recognized Expert Contributor
      • Aug 2007
      • 671

      #3
      Read: C-FAQ. It's an undefined expression.

      Sickofant, your explanation is incorrect. The postincrement does not mean after the statement.

      Comment

      • JosAH
        Recognized Expert MVP
        • Mar 2007
        • 11453

        #4
        Altering a modifiable left-hand value in an expression more than once (*) causes
        'undefined behaviour' as defined by the Standard, so discussing what the
        outcome of the expression above will or should be is useless. Evaluating
        that thing can even make daemons fly out of your nose: it is undefined.

        kind regards,

        Jos

        (*) the actual text defines a 'sequence point'; an lhv may only be altered at most
        once before that sequence point is reached.

        Comment

        • arnaudk
          Contributor
          • Sep 2007
          • 425

          #5
          Jos, just out of curiosity, is that also true for Java?

          Comment

          • JosAH
            Recognized Expert MVP
            • Mar 2007
            • 11453

            #6
            Originally posted by arnaudk
            Jos, just out of curiosity, is that also true for Java?
            No, Java defines the evaluation as strictly from left to right and 'eager', i.e. an
            assignment is performed as soon as possible (that includes the ++ and --
            operators). So in Java the following results in b=35:

            [code=java]
            int a= 5;
            int b= a++*++a;
            [/code]

            I find it a mixed blessing because its evaluation scheme disallows for a bit of
            optimization in certain expressions.

            In C (and C++) daemons may fly out of your nose of course ;-)

            kind regards,

            Jos

            Comment

            • arnaudk
              Contributor
              • Sep 2007
              • 425

              #7
              OK. Thanks for the replies!

              Comment

              • questionit
                Contributor
                • Feb 2007
                • 553

                #8
                Originally posted by JosAH
                No, Java defines the evaluation as strictly from left to right and 'eager', i.e. an
                assignment is performed as soon as possible (that includes the ++ and --
                operators). So in Java the following results in b=35:

                [code=java]
                int a= 5;
                int b= a++*++a;
                [/code]

                I find it a mixed blessing because its evaluation scheme disallows for a bit of
                optimization in certain expressions.

                In C (and C++) daemons may fly out of your nose of course ;-)

                kind regards,

                Jos
                Jos,

                Just wondering after reading your above piece of code:

                What would remain the advantage of post-increment operator (++) in this case when it is behaving same as pre-increment operator?

                [code=c]
                int a= 5;
                int b= a++*++a;
                [/code]

                It would be expected of a++ to increment after the statement and for ++a to increment during the statement to see their different. If in above example a++ is becoming 6 and then ++a is becoming 7, means both the operators (pre & post increment) are doing the same thing, where is the main different between them then?

                Btw, did i not get what you mean by your statement" an assignment is performed as soon as possible" ... do you mean result of a++ is first assigned to the variable b and then this result is further evaluated with rest of the expression: * ++a ?


                Regards
                Qi
                Last edited by questionit; May 18 '08, 09:58 AM. Reason: add some more to question

                Comment

                • JosAH
                  Recognized Expert MVP
                  • Mar 2007
                  • 11453

                  #9
                  Originally posted by questionit
                  Jos,

                  Just wondering after reading your above piece of code:

                  What would remain the advantage of post-increment operator (++) in this case when it is behaving same as pre-increment operator?

                  [code=c]
                  int a= 5;
                  int b= a++*++a;
                  [/code]

                  It would be expected of a++ to increment after the statement and for ++a to increment during the statement to see their different. If in above example a++ is becoming 6 and then ++a is becoming 7, means both the operators (pre & post increment) are doing the same thing, where is the main different between them then?
                  No, the semantics of the a++ expression are: the value is the old value of a and
                  the variable a is incremented. The semantics of ++a are: increment a and the
                  value of the expression is the new value of a.

                  It all has nothing to do with "after the expresssion": things happen in a stricty
                  defined way in Java, so a++*++a is evaluated as:

                  1) take old value of a (5) and increment a (a is now 6)
                  2) the left hand operand of the * operator is 5
                  3 increment a (a is now 7) and get its value
                  4 the right hand operand of the * operator is 7
                  5 multiply the left and right hand operands values (5 and 7)
                  6) the result is 5*7 == 35

                  In C and C++ steps 1) and 3) are not allowed together in one expression because
                  the both alter the value of a modifiable left hand value (variable a).

                  kind regards,

                  Jos

                  Comment

                  • fressanme
                    New Member
                    • Apr 2007
                    • 36

                    #10
                    excuse me, but i would like to clarify something on the topic..

                    isnt it that "variableName++ " implies that "variableNa me" is to be incremented by one, after the statement/statements are done? so in this case, i guess what happens is:

                    a = 5;

                    lets say "a++ * ++a = x"

                    as far as i know:

                    a++ = 5; since the statement has not finished executing yet; and
                    ++a = 6; since "a" is already incremented by one even before the statement executes; so

                    = (a++) * (++a)
                    = 5 * 6
                    = 30

                    i dont know if that's right or wrong..just wanted to clarify if this one is right or wrong..have a nice day!

                    Comment

                    • JosAH
                      Recognized Expert MVP
                      • Mar 2007
                      • 11453

                      #11
                      Originally posted by fressanme
                      i dont know if that's right or wrong..just wanted to clarify if this one is right or wrong..have a nice day!
                      Sorry, it is dead wrong; have a nice day too.

                      kind regards,

                      Jos

                      Comment

                      • arnaudk
                        Contributor
                        • Sep 2007
                        • 425

                        #12
                        My understanding of the post increment is that the value is incremented as soon as it is read: Since * acts from left to right, it reads a=5. This is the point where a is incremented because it has just been read. In java, things proceed like Jos described and in C/C++ you get an answer that defies all logic (for my compiler, at least, since strictly speaking any further toying with a apparently leads to undefined behaviour according to the standard).

                        Comment

                        • arnaudk
                          Contributor
                          • Sep 2007
                          • 425

                          #13
                          Here is a catalog of results made with VC++2008 (a is reset to 5 before each line):
                          [code=text]
                          a++ * a = 25, now a = 6.
                          a * a++ = 25, now a = 6.
                          ++a * a = 36, now a = 6.
                          a * ++a = 36, now a = 6.
                          a++ * ++a = 36, now a = 7.
                          a++ * a++ = 25, now a = 7.
                          ++a * ++a = 49, now a = 7.
                          ++a * a++ = 36, now a = 7.
                          [/code]
                          It appears that increments are made either entirely before or entirely after the multiplication operation so my previous statement wasn't correct, see line 4, for example. That it defies all logic is true, however.
                          [update: I tried it with GCC 3.4.6 on Redhat and got identical results.]

                          Comment

                          • oler1s
                            Recognized Expert Contributor
                            • Aug 2007
                            • 671

                            #14
                            My understanding of the post increment is that the value is incremented as soon as it is read:
                            Is this an understanding you got from reading the standard (you can get the circa 98 drafts online) or something you imagine is happening? Because there is a precise definition of how post increment works, and that definition is not what you described.

                            Here's the thing about undefined operations. Trying to put logic to them doesn't work, because you can't define undefined expressions. Maybe you can figure out how a certain compiler tends to interpret such undefined operations. Frankly, I fail to see the value gained.

                            Comment

                            • arnaudk
                              Contributor
                              • Sep 2007
                              • 425

                              #15
                              Originally posted by oler1s
                              ...that definition is not what you described.
                              Sorry, I thought that was clear from my previous post.
                              Originally posted by oler1s
                              ...you can't define undefined expressions.
                              You don't seriously think I was trying to do this? It was merely unclear to me precisely what was and wasn't defined. Anyway, I found the relevant portion in the standard so, for completeness, here it is:

                              ISO/IEC 14882:1998, section 5.0, paragraph 4: "Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored."

                              Expressions like a*++a, whilst modifying the value of a only once, access it to determine the (incremented) value to be stored and again to determine the outcome of the multiplication, counter to the wording of the standard.

                              Comment

                              Working...