Increment and order of evaluation

Discussion in 'C Programming' started by Asbjørn Sæbø, Dec 14, 2007.

  1. Lint gives me warning about a code fragment, saying that the result is
    dependent upon order of evaluation. I fail to see that it can be so.
    The code fragment below illustrates the situation:

    -------------------
    #define CONSTANT SOME_VALUE
    uint16_t my_var = <another_value>;

    my_var = ++my_var % CONSTANT;
    ----------------------

    How can the order of evaluation affect the result of this calculation?
    My reasoning is that the increment operator has higher presedence than
    the modulo operator, and should therefore be applied to my_var before
    the modulo operator is applied to my_var, regardless of which side of
    the modulo operator is evaluated first. Therefore, order of
    evaluation should not influence the result?

    Am I correct? And if not, how and why?


    Asbjørn Sæbø
     
    Asbjørn Sæbø, Dec 14, 2007
    #1
    1. Advertising

  2. Asbjørn Sæbø

    pete Guest

    =?utf-8?b?QXNiasO4cm4gU8OmYsO4?= wrote:
    >
    > Lint gives me warning about a code fragment, saying that the result is
    > dependent upon order of evaluation. I fail to see that it can be so.
    > The code fragment below illustrates the situation:
    >
    > -------------------
    > #define CONSTANT SOME_VALUE
    > uint16_t my_var = <another_value>;
    >
    > my_var = ++my_var % CONSTANT;
    > ----------------------
    >
    > How can the order of evaluation affect the result of this calculation?
    > My reasoning is that the increment operator has higher presedence than
    > the modulo operator, and should therefore be applied to my_var before
    > the modulo operator is applied to my_var, regardless of which side of
    > the modulo operator is evaluated first. Therefore, order of
    > evaluation should not influence the result?
    >
    > Am I correct? And if not, how and why?


    Your code has undefined behavior.
    There's no sequence point in between your two assignment
    operations on my_var.

    Your code is a special case of
    i = ++i;

    The problem is that the increment assignment can take place
    either prior to or after the other assignment operation.

    While this seems like it could result
    in only one of two different values,
    the standard committee has decided that code like that is so crappy,
    that the best thing to do
    is to lump it in together with all other code
    that tries to modify an object more than once
    without an interveening sequence point,
    and declare it as invoking "undefined behavior".

    "Sequence points" is a major concept in C.
    You can get a free copy of a public draft of the standard,
    on the internet, that will explain sequence points.
    Google for it.
    After you read about sequence points,
    you should probably want to discuss it again here.

    --
    pete
     
    pete, Dec 14, 2007
    #2
    1. Advertising

  3. Asbjørn Sæbø

    Eric Sosman Guest

    Asbjørn Sæbø wrote:
    > Lint gives me warning about a code fragment, saying that the result is
    > dependent upon order of evaluation. I fail to see that it can be so.
    > The code fragment below illustrates the situation:
    >
    > -------------------
    > #define CONSTANT SOME_VALUE
    > uint16_t my_var = <another_value>;
    >
    > my_var = ++my_var % CONSTANT;
    > ----------------------
    >
    > How can the order of evaluation affect the result of this calculation?
    > My reasoning is that the increment operator has higher presedence than
    > the modulo operator, and should therefore be applied to my_var before
    > the modulo operator is applied to my_var, regardless of which side of
    > the modulo operator is evaluated first. Therefore, order of
    > evaluation should not influence the result?
    >
    > Am I correct? And if not, how and why?


    Your argument is right, but you're arguing about the
    wrong thing. See Question 3.3 in the comp.lang.c Frequently
    Asked Questions (FAQ) list at <http://www.c-faq.com/>.

    --
    Eric Sosman
    lid
     
    Eric Sosman, Dec 14, 2007
    #3
  4. pete <> writes:

    > =?utf-8?b?QXNiasO4cm4gU8OmYsO4?= wrote:


    > > -------------------
    > > #define CONSTANT SOME_VALUE
    > > uint16_t my_var = <another_value>;
    > >
    > > my_var = ++my_var % CONSTANT;
    > > ----------------------



    > Your code is a special case of
    > i = ++i;
    >
    > The problem is that the increment assignment can take place
    > either prior to or after the other assignment operation.


    OK, now I see it. Thanks to you and to Eric!

    I'll have to read up on those sequence points.

    Asbjørn
     
    Asbjørn Sæbø, Dec 14, 2007
    #4
  5. Asbjørn Sæbø

    Chris Dollin Guest

    Asbjørn Sæbø wrote:

    > Lint gives me warning about a code fragment, saying that the result is
    > dependent upon order of evaluation. I fail to see that it can be so.
    > The code fragment below illustrates the situation:
    >
    > -------------------
    > #define CONSTANT SOME_VALUE
    > uint16_t my_var = <another_value>;
    >
    > my_var = ++my_var % CONSTANT;
    > ----------------------
    >
    > How can the order of evaluation affect the result of this calculation?


    The assignment may be done before or after the increment.

    > My reasoning is that the increment operator has higher presedence than
    > the modulo operator,


    Yes, but that's got (almost) nothing to do with it. All precedence and
    associativity do is define which operators have which operands [1].
    They do /not/ define order-of-evaluation, which is provided by
    operator-specific rules, the most commonly applicable rule being
    "the order is unspecified"; order of evaluation is defined for
    &&, ||, ?:, and the comma operator and that's about it [2].

    So in your expression above

    my_var = ++my_var % CONSTANT

    the grouping is made explicit with

    my_var = ((++my_var) % CONSTANT)

    The expression `++E` means "compute the value `E+1`, return that as
    the value of this expression, and store that value back into the
    same location /by the next sequence point/". The time of the update
    is loosely specified to allow implementors latitude for efficiency.
    The store-back doesn't need to be immediate and it doesn't need to
    be before the assignment. (In fact, multiple assignments to a location
    with no intervening sequence point /specifically/ results in undefined
    behaviour -- all bets are off, the compiler can do whatever it likes.)

    Why you'd /want/ to write the code above is about as clear as its
    meaning:

    my_var = (my_var + 1) % CONSTANT;

    is, at a guess, what you really wanted.

    [1] And strictly, in C, the grammar that defines that doesn't /use/
    precedence and associativity, it writes them out longhand; P&A
    are just useful shorthands.

    [2] Vague feeling that I've forgotten something that I'll remember
    just as this post commits ...

    --
    Chris "boom++" Dollin

    Hewlett-Packard Limited registered no:
    registered office: Cain Road, Bracknell, Berks RG12 1HN 690597 England
     
    Chris Dollin, Dec 14, 2007
    #5
  6. Asbjørn Sæbø

    Willem Guest

    Asbjørn wrote:
    ) OK, now I see it. Thanks to you and to Eric!
    )
    ) I'll have to read up on those sequence points.

    There's no reason to code it like that anyway. If you just want
    the value of my_var plus one, you're better off writing ' (my_var + 1) '.


    SaSW, Willem
    --
    Disclaimer: I am in no way responsible for any of the statements
    made in the above text. For all I know I might be
    drugged or something..
    No I'm not paranoid. You all think I'm paranoid, don't you !
    #EOT
     
    Willem, Dec 14, 2007
    #6
  7. Asbjørn Sæbø <> writes:

    > Lint gives me warning about a code fragment, saying that the result is
    > dependent upon order of evaluation. I fail to see that it can be so.
    > The code fragment below illustrates the situation:
    >
    > -------------------
    > #define CONSTANT SOME_VALUE
    > uint16_t my_var = <another_value>;
    >
    > my_var = ++my_var % CONSTANT;
    > ----------------------
    >
    > How can the order of evaluation affect the result of this
    > calculation?


    I think it would be better for lint to quote the reason why the above
    has undefined behaviour -- an object is being modified twice between
    one sequence point and the next. See:
    http://c-faq.com/expr/ieqiplusplus.html

    > My reasoning is that the increment operator has higher presedence than
    > the modulo operator, and should therefore be applied to my_var before
    > the modulo operator is applied to my_var, regardless of which side of
    > the modulo operator is evaluated first. Therefore, order of
    > evaluation should not influence the result?


    Operator precedence does not come into it. The requirement that every
    object be modified only once between any two sequence points is
    violated no matter what evaluation order is used.

    --
    Ben.
     
    Ben Bacarisse, Dec 14, 2007
    #7
    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. Rajorshi

    order of evaluation of increment operators

    Rajorshi, Jul 22, 2004, in forum: C Programming
    Replies:
    7
    Views:
    555
    Keith Thompson
    Jul 22, 2004
  2. Replies:
    104
    Views:
    11,076
    Jordan Abel
    Oct 28, 2005
  3. Replies:
    99
    Views:
    2,531
    eliza81
    Jun 11, 2010
  4. Alf P. Steinbach /Usenet
    Replies:
    0
    Views:
    913
    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:
    564
    Peter J. Holzer
    Nov 23, 2008
Loading...

Share This Page