Increment operator precedence

Discussion in 'C Programming' started by nl, Feb 15, 2008.

  1. nl

    nl Guest

    Hi, I am confused about the order of operation for the increment
    operater ++. I wrote the program below trying to clear my doubts, but
    it just got me more confused. For example, in the second case, I
    thought that ++x will increment x to 2. and since y = 3, that makes z
    = 2 + 3 =5. However the result shows that z =4.

    Would greatly appreciate any help.

    #include <stdio.h>

    int main(void)
    {
    int x=1, y=1, z=0;

    z = x++ +( y += x++) ;

    printf("\n\n%d %d %d\n\n", x, y, z);
    x=1, y=1, z=0;

    z = x++ +( y += ++x) ;
    printf("\n\n%d %d %d\n\n", x, y, z);

    x=1, y=1, z=0;

    z = ++x +( y += x++) ;
    printf("\n\n%d %d %d\n\n", x, y, z);

    x=1, y=1, z=0;
    z = ++x +( y += ++x) ;

    printf("\n\n%d %d %d\n\n", x, y, z);
    return 0;
    }


    The results:

    2 2 3


    2 3 4


    3 3 5


    3 4 6
     
    nl, Feb 15, 2008
    #1
    1. Advertising

  2. nl

    raghu Guest

    On Feb 15, 12:09 pm, nl <> wrote:
    > Hi, I am confused about the order of operation for the increment
    > operater ++. I wrote the program below trying to clear my doubts, but
    > it just got me more confused. For example, in the second case, I
    > thought that ++x will increment x to 2. and since y = 3, that makes z
    > = 2 + 3 =5. However the result shows that z =4.
    >
    > Would greatly appreciate any help.
    >
    > #include <stdio.h>
    >
    > int main(void)
    > {
    >     int x=1, y=1, z=0;
    >
    >     z = x++ +( y += x++) ;
    >
    >     printf("\n\n%d %d %d\n\n", x, y, z);
    >     x=1, y=1, z=0;
    >
    >     z = x++ +( y += ++x) ;
    >     printf("\n\n%d %d %d\n\n", x, y, z);
    >
    >     x=1, y=1, z=0;
    >
    >     z = ++x +( y += x++) ;
    >     printf("\n\n%d %d %d\n\n", x, y, z);
    >
    >     x=1, y=1, z=0;
    >     z = ++x +( y += ++x) ;
    >
    >     printf("\n\n%d %d %d\n\n", x, y, z);
    >     return 0;
    >
    > }
    >
    > The results:
    >
    > 2 2 3
    >
    > 2 3 4
    >
    > 3 3 5
    >
    > 3 4 6


    The results are correct.

    Where did u find the problem?
     
    raghu, Feb 15, 2008
    #2
    1. Advertising

  3. nl

    Ian Collins Guest

    nl wrote:
    > Hi, I am confused about the order of operation for the increment
    > operater ++. I wrote the program below trying to clear my doubts, but
    > it just got me more confused. For example, in the second case, I
    > thought that ++x will increment x to 2. and since y = 3, that makes z
    > = 2 + 3 =5. However the result shows that z =4.
    >
    > Would greatly appreciate any help.
    >
    > #include <stdio.h>
    >
    > int main(void)
    > {
    > int x=1, y=1, z=0;
    >
    > z = x++ +( y += x++) ;
    >

    The above invokes undefined behaviour, you can't increment x twice
    without a sequence point.

    --
    Ian Collins.
     
    Ian Collins, Feb 15, 2008
    #3
  4. On 15 Feb, 08:25, raghu <> wrote:
    > On Feb 15, 12:09 pm, nl <> wrote:


    > > Hi, I am confused about the order of operation for the increment
    > > operater ++. I wrote the program below trying to clear my doubts, but
    > > it just got me more confused. For example, in the second case, I
    > > thought that ++x will increment x to 2. and since y = 3, that makes z
    > > = 2 + 3 =5. However the result shows that z =4.

    >
    > > Would greatly appreciate any help.

    >
    > > #include <stdio.h>

    >
    > > int main(void)
    > > {
    > >     int x=1, y=1, z=0;

    >
    > >     z = x++ +( y += x++) ;

    >
    > >     printf("\n\n%d %d %d\n\n", x, y, z);
    > >     x=1, y=1, z=0;

    >
    > >     z = x++ +( y += ++x) ;
    > >     printf("\n\n%d %d %d\n\n", x, y, z);

    >
    > >     x=1, y=1, z=0;

    >
    > >     z = ++x +( y += x++) ;
    > >     printf("\n\n%d %d %d\n\n", x, y, z);

    >
    > >     x=1, y=1, z=0;
    > >     z = ++x +( y += ++x) ;

    >
    > >     printf("\n\n%d %d %d\n\n", x, y, z);
    > >     return 0;

    >
    > > }

    >
    > > The results:

    >
    > > 2 2 3

    >
    > > 2 3 4

    >
    > > 3 3 5

    >
    > > 3 4 6

    >
    > The results are correct.


    no. All the instances in the example invoke Undefined Behaviour
    so the implementation can do whatever it pleases. In a sense *any*
    result is "correct". I'd prefer to say expecting any particular
    result is wrong.

    > Where did u find the problem


    please don't use "txt" speak in your posts.


    --
    Nick Keighley
     
    Nick Keighley, Feb 15, 2008
    #4
  5. nl

    Chris Dollin Guest

    nl wrote:

    > Hi, I am confused about the order of operation for the increment
    > operater ++. I wrote the program below trying to clear my doubts, but
    > it just got me more confused. For example, in the second case, I
    > thought that ++x will increment x to 2. and since y = 3, that makes z
    > = 2 + 3 =5. However the result shows that z =4.
    >
    > Would greatly appreciate any help.
    >
    > #include <stdio.h>
    >
    > int main(void)
    > {
    > int x=1, y=1, z=0;
    >
    > z = x++ +( y += x++) ;


    Not allowed.

    > printf("\n\n%d %d %d\n\n", x, y, z);
    > x=1, y=1, z=0;
    >
    > z = x++ +( y += ++x) ;


    Not allowed.

    > printf("\n\n%d %d %d\n\n", x, y, z);
    >
    > x=1, y=1, z=0;
    >
    > z = ++x +( y += x++) ;


    Not allowed.

    > printf("\n\n%d %d %d\n\n", x, y, z);
    >
    > x=1, y=1, z=0;
    > z = ++x +( y += ++x) ;


    (All together now:) Not allowed.
    >
    > printf("\n\n%d %d %d\n\n", x, y, z);
    > return 0;
    > }


    All four statements lead to Undefined Behaviour: C does not specify and
    does not care how the implementation chooses to implement them. Taking

    > z = x++ +( y += x++) ;


    as the example, we see it tries to update `x` twice in the same
    statement. This is /specifically/ not allowed by the Standard [1].
    (I believe this is to allow implementors enough slack to do efficient
    code generation, but it also eliminates some chances of confusion.)

    In the expression `a + b`, it's not specified whether `a` or `b` is
    evaluated first. In the expressions `a++` and `++a, it's not specified
    when `a` is incremented, so long as its done by the end of the statement.
    In the expression `a = b`, it's not specified whether (the address of)
    `a` is evaluated before (the value of) `b`. So even without the Thou
    Shalt Not for multiple updates of `x`, in

    > int x=1, y=1, z=0;
    > z = x++ +( y += x++) ;


    `x`, `y`, and `z` could end up with all sorts of different values;
    that in fact they are allowed to end up with /any values at all/,
    or an exception could be thrown [2], or /other/ variables could
    be updated, is worse but not concept-breakingly worse.

    [1] Actually the Standard talks about "sequence points", which are
    the points in an expression where any side-effects of the
    expression must have been committed; end-of-statement is the
    most common, but the others are the end of the left operand of
    `&&`, `||`, `?:`, the comma-operator `,` (NOT the argument-
    separator `,`),, and function-call.

    [2] Yes, C doesn't have exceptions -- but Undefined Behaviour takes
    you outside where C cares ...

    --
    "It was the dawn of the third age of mankind." /Babylon 5/

    Hewlett-Packard Limited Cain Road, Bracknell, registered no:
    registered office: Berks RG12 1HN 690597 England
     
    Chris Dollin, Feb 15, 2008
    #5
  6. nl

    John Bode Guest

    On Feb 15, 2:09 am, nl <> wrote:
    > Hi, I am confused about the order of operation for the increment
    > operater ++. I wrote the program below trying to clear my doubts, but
    > it just got me more confused. For example, in the second case, I
    > thought that ++x will increment x to 2. and since y = 3, that makes z
    > = 2 + 3 =5. However the result shows that z =4.
    >


    As others have pointed out, attempting to update the same object more
    than once between sequence points results in undefined behavior; *any*
    result is considered "correct", because the standard places no
    restrictions on the compiler.

    Any expression of the forms

    x = x++
    i++ + i++
    a = i++ (or a[i++] = i)

    will result in undefined behavior.

    Some things to remember when using the autoincrement and autodecrement
    operators:

    1. Both a++ and a-- evaluate to the current value of a, ++a evaluates
    to the current value of a + 1, --a evaluates to the current value of a
    - 1, and as a *side effect*, the value of a is updated. Note that the
    side effect does not have to be applied immediately after the
    expression has been evaluated. Depending on the compiler, side
    effects may be deferred until all other expressions have been
    evaluated, or until some subset of expressions have been evaluated.
    For example, given the statement

    z = a++ * --b;

    z will get the current value of a multiplied by the current value of
    b-1. However, exactly when a and b get updated is not fixed; both may
    be updated immediately after they're evaluated, they may be updated
    only after both have been evaluated, or they may be updated after z
    has been assigned. The only rule is that both have been updated by
    the end of the statement. Any of the following are possible:

    t1 <- a // a and b are updated immediately after evaluation
    a <- a + 1
    t2 <- b - 1
    b <- b - 1
    z <- t1 * t2

    or

    t1 <- a // a and b are updated at the end
    t2 <- b - 1
    z <- t1 * t2
    a <- a + 1
    b <- b - 1


    2. a-- evaluates to the current value of a, --a evaluates to the
    current value of a - 1, and as a *side effect*, the value of a is
    decremented. Same disclaimer as above about when the side effect is
    applied.

    3. Precedence and order of evaluation are two different things.
    Given the expression

    a() * b() + c()

    precedence rules require that the result of a() be multiplied by the
    result of b() before the result of c() is added. However, there's no
    guarantee that a() will be *evaluated* before b() or c(). The
    compiler may arrange things so that c() is called *first*, and its
    result is stored until a() and b() have been evaluated and their
    results multiplied together. Similarly, with an expression like

    a++ * b++ + c++

    there's no guarantee that a has been evaluated or incremented before
    either c or b have been evaluated.
     
    John Bode, Feb 15, 2008
    #6
  7. nl

    CBFalconer Guest

    nl wrote:
    >
    > Hi, I am confused about the order of operation for the increment
    > operater ++. I wrote the program below trying to clear my doubts,
    > but it just got me more confused. For example, in the second
    > case, I thought that ++x will increment x to 2. and since y = 3,
    > that makes z = 2 + 3 =5. However the result shows that z =4.
    >
    > Would greatly appreciate any help.
    >
    > #include <stdio.h>
    >
    > int main(void) {
    > int x=1, y=1, z=0;
    >
    > z = x++ +( y += x++) ;

    ^ ^
    [1] [2]

    Why do you assume that [1] precedes [2], or that [2] precedes [1]?
    If you read the C standard you will see that the expression is
    undefined in standard C. Any result meets the requirements.

    --
    [mail]: Chuck F (cbfalconer at maineline dot net)
    [page]: <http://cbfalconer.home.att.net>
    Try the download section.



    --
    Posted via a free Usenet account from http://www.teranews.com
     
    CBFalconer, Feb 15, 2008
    #7
  8. nl

    Jack Klein Guest

    On Fri, 15 Feb 2008 07:22:16 -0800 (PST), John Bode
    <> wrote in comp.lang.c:

    > On Feb 15, 2:09 am, nl <> wrote:
    > > Hi, I am confused about the order of operation for the increment
    > > operater ++. I wrote the program below trying to clear my doubts, but
    > > it just got me more confused. For example, in the second case, I
    > > thought that ++x will increment x to 2. and since y = 3, that makes z
    > > = 2 + 3 =5. However the result shows that z =4.
    > >

    >
    > As others have pointed out, attempting to update the same object more
    > than once between sequence points results in undefined behavior; *any*
    > result is considered "correct", because the standard places no
    > restrictions on the compiler.
    >
    > Any expression of the forms
    >
    > x = x++
    > i++ + i++
    > a = i++ (or a[i++] = i)
    >
    > will result in undefined behavior.
    >
    > Some things to remember when using the autoincrement and autodecrement
    > operators:


    ITYM "preincrement" and "predecrement", rather than "autoincrement"
    and "autodecrement".

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://c-faq.com/
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, Feb 16, 2008
    #8
  9. raghu wrote:
    >
    > On Feb 15, 12:09 pm, nl <> wrote:
    > > Hi, I am confused about the order of operation for the increment
    > > operater ++. I wrote the program below trying to clear my doubts, but

    [...]
    > > z = x++ +( y += x++) ;

    [...]
    > > z = x++ +( y += ++x) ;

    [...]
    > > z = ++x +( y += x++) ;

    [...]
    > > z = ++x +( y += ++x) ;

    [...]
    > > The results:
    > >
    > > 2 2 3
    > >
    > > 2 3 4
    > >
    > > 3 3 5
    > >
    > > 3 4 6

    >
    > The results are correct.


    Well, "correct" in the sense that "undefined behavior can result
    in anything happening, including what you thought you meant to do".

    > Where did u find the problem?


    I don't believe that Mr. Thant was looking for any problems.

    --
    +-------------------------+--------------------+-----------------------+
    | Kenneth J. Brody | www.hvcomputer.com | #include |
    | kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
    +-------------------------+--------------------+-----------------------+
    Don't e-mail me at: <mailto:>
     
    Kenneth Brody, Feb 17, 2008
    #9
  10. nl

    John Bode Guest

    On Feb 15, 10:30 pm, Jack Klein <> wrote:
    > On Fri, 15 Feb 2008 07:22:16 -0800 (PST), John Bode
    > <> wrote in comp.lang.c:
    >
    >
    >
    > > On Feb 15, 2:09 am, nl <> wrote:
    > > > Hi, I am confused about the order of operation for the increment
    > > > operater ++. I wrote the program below trying to clear my doubts, but
    > > > it just got me more confused. For example, in the second case, I
    > > > thought that ++x will increment x to 2. and since y = 3, that makes z
    > > > = 2 + 3 =5. However the result shows that z =4.

    >
    > > As others have pointed out, attempting to update the same object more
    > > than once between sequence points results in undefined behavior; *any*
    > > result is considered "correct", because the standard places no
    > > restrictions on the compiler.

    >
    > > Any expression of the forms

    >
    > > x = x++
    > > i++ + i++
    > > a = i++ (or a[i++] = i)

    >
    > > will result in undefined behavior.

    >
    > > Some things to remember when using the autoincrement and autodecrement
    > > operators:

    >
    > ITYM "preincrement" and "predecrement", rather than "autoincrement"
    > and "autodecrement".
    >


    I've always used "auto*crement" when referring to both pre- and
    postfix forms, and IINM the rules I listed apply to both.

    Am I abusing terminology again?
     
    John Bode, Feb 18, 2008
    #10
  11. In article <>,
    John Bode <> wrote:

    >> ITYM "preincrement" and "predecrement", rather than "autoincrement"
    >> and "autodecrement".


    >I've always used "auto*crement" when referring to both pre- and
    >postfix forms [...]


    >Am I abusing terminology again?


    The terms "autoincrement" and "autodecrement" were used for register
    address modes on the PDP-11. That made sense: they were modes for
    calculating an address, that had an added side effect of incrementing
    or decrementing.

    Carrying the terms over to the analogous C operators is natural, even
    if there is less need to emphasise any automatic-ness.

    -- Richard
    --
    :wq
     
    Richard Tobin, Feb 18, 2008
    #11
  12. John Bode <> writes:
    > On Feb 15, 10:30 pm, Jack Klein <> wrote:
    >> On Fri, 15 Feb 2008 07:22:16 -0800 (PST), John Bode
    >> <> wrote in comp.lang.c:

    [...]
    >> > Some things to remember when using the autoincrement and autodecrement
    >> > operators:

    >>
    >> ITYM "preincrement" and "predecrement", rather than "autoincrement"
    >> and "autodecrement".
    >>

    >
    > I've always used "auto*crement" when referring to both pre- and
    > postfix forms, and IINM the rules I listed apply to both.
    >
    > Am I abusing terminology again?


    In my experience, the term autoincrement refers to a certain
    addressing mode on the PDP-11 and other architectures which causes the
    address stored in a CPU register to be automatically incremented when
    you access memory through it.

    The terms {pre,post}{in,de}crement seems clearer and more applicable
    to the C "++" and "--" operators.

    --
    Keith Thompson (The_Other_Keith) <>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Feb 18, 2008
    #12
  13. CBFalconer wrote:
    >
    > nl wrote:
    > >
    > > Hi, I am confused about the order of operation for the increment
    > > operater ++. I wrote the program below trying to clear my doubts,
    > > but it just got me more confused. For example, in the second
    > > case, I thought that ++x will increment x to 2. and since y = 3,
    > > that makes z = 2 + 3 =5. However the result shows that z =4.
    > >
    > > Would greatly appreciate any help.
    > >
    > > #include <stdio.h>
    > >
    > > int main(void) {
    > > int x=1, y=1, z=0;
    > >
    > > z = x++ +( y += x++) ;

    > ^ ^
    > [1] [2]
    >
    > Why do you assume that [1] precedes [2], or that [2] precedes [1]?
    > If you read the C standard you will see that the expression is
    > undefined in standard C. Any result meets the requirements.


    It seems to be a not-so-uncommon misconception that expressions
    inside of parentheses must be performed before anything outside
    of parentheses. They appear to base this on cases such as:

    a * ( b + c )

    where the value of the "b + c" expression must be evaluated before
    the multiplication takes places. Of course, nothing requires that
    this be taken to mean that "a" cannot be evaluated first. For
    example, a stack-based machine may generate:

    push a
    push b
    push c
    add
    mult

    In fact, for cases such as:

    a + ( b - c )

    it is not even necessary that "b - c" be evaluated separately, as
    the expression is identical to:

    ( a + b ) - c

    and the "as-if" rule permits the compiler to treat the two the
    same.

    --
    +-------------------------+--------------------+-----------------------+
    | Kenneth J. Brody | www.hvcomputer.com | #include |
    | kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
    +-------------------------+--------------------+-----------------------+
    Don't e-mail me at: <mailto:>
     
    Kenneth Brody, Feb 19, 2008
    #13
  14. nl

    Guest

    Kenneth Brody <> wrote:
    >
    > In fact, for cases such as:
    >
    > a + ( b - c )
    >
    > it is not even necessary that "b - c" be evaluated separately, as
    > the expression is identical to:
    >
    > ( a + b ) - c
    >
    > and the "as-if" rule permits the compiler to treat the two the
    > same.


    Only if the compiler can be certain that a+b won't overflow or that
    overflow is silent and invertible (or that b-c will overflow, in which
    case all bets are off).

    -Larry Jones

    What a stupid world. -- Calvin
     
    , Feb 19, 2008
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. David Frauzel

    Operator precedence

    David Frauzel, May 13, 2004, in forum: Perl
    Replies:
    2
    Views:
    545
    Luc Van Hove
    May 17, 2004
  2. Replies:
    104
    Views:
    11,030
    Jordan Abel
    Oct 28, 2005
  3. Replies:
    99
    Views:
    2,511
    eliza81
    Jun 11, 2010
  4. Alf P. Steinbach /Usenet
    Replies:
    0
    Views:
    900
    Alf P. Steinbach /Usenet
    May 22, 2011
  5. Peng Yu

    post increment or pre increment?

    Peng Yu, Nov 21, 2008, in forum: Perl Misc
    Replies:
    7
    Views:
    530
    Peter J. Holzer
    Nov 23, 2008
Loading...

Share This Page