Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Increment and order of evaluation

Reply
Thread Tools

Increment and order of evaluation

 
 
Asbjørn Sæbø
Guest
Posts: n/a
 
      12-14-2007

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ø

 
Reply With Quote
 
 
 
 
pete
Guest
Posts: n/a
 
      12-14-2007
=?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
 
Reply With Quote
 
 
 
 
Eric Sosman
Guest
Posts: n/a
 
      12-14-2007
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
http://www.velocityreviews.com/forums/(E-Mail Removed)lid
 
Reply With Quote
 
Asbjørn Sæbø
Guest
Posts: n/a
 
      12-14-2007
pete <(E-Mail Removed)> 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

 
Reply With Quote
 
Chris Dollin
Guest
Posts: n/a
 
      12-14-2007
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

 
Reply With Quote
 
Willem
Guest
Posts: n/a
 
      12-14-2007
Asbjrn 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
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      12-14-2007
Asbjørn Sæbø <(E-Mail Removed)> 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.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Post increment ++ has higher precedence than pre increment ++. Why? Alf P. Steinbach /Usenet C++ 0 05-22-2011 12:03 PM
why prefix increment is faster than postfix increment? jrefactors@hotmail.com C++ 99 06-11-2010 12:51 PM
post increment or pre increment? Peng Yu Perl Misc 7 11-23-2008 11:44 PM
why prefix increment is faster than postfix increment? jrefactors@hotmail.com C Programming 104 10-27-2005 11:44 PM
order of evaluation of increment operators Rajorshi C Programming 7 07-22-2004 08:04 PM



Advertisments