C/C++ Ambiguity in Order of Evaluation

R

Richard Bos

Rasjid said:
This is from msdn2.microsoft, under C Reference Manual:-
"Precedence and Order of Evaluation

The precedence and associativity of C operators affect the grouping
and evaluation of operands in expressions.

Unless this is a MSVC++##4.0 manual, and not a C Reference Manual as
such, that is simply a lie.
I am not sure if anyone take issue with the paragraph.

Oh, I should hope so. It's wrong. Of course, it's Microsoft, so no
surprise there; they always insist that their way is the only way, and
industry standards exist so they can break them.
I some parts or niches of the world, information takes 40 years to get
through.

Tough cookies - 40 years ago it was 1967, and C wasn't invented yet.
Had I known it is undefined, I'll do this/rather it should have been
this :-
If ( exprA && ((u = bitboard1 | bitboard2) , (w = (u - ((u & -u) <<
1)))) ){

*Brrrrr*

Vade retro, Perlhackere!

Richard
 
R

Richard Heathfield

CBFalconer said:
If you are going to post here regularly you need to learn not to
top-post, and to limit your line lengths (under 72 is good, 67 is
better).

Chuck, if you are going to post content-free material, could you please
adjust the subject line, like Default User does? That way, I can filter
it out.

Thanks.
 
C

CBFalconer

Rasjid said:
.... snip ...

This is from msdn2.microsoft, under C Reference Manual:-
"Precedence and Order of Evaluation

The precedence and associativity of C operators affect the grouping
and evaluation of operands in expressions. An operator's precedence
is meaningful only if other operators with higher or lower
precedence are present. Expressions with higher-precedence
operators are evaluated first. Precedence can also be described by
the word "binding." Operators with a higher precedence are said to
have tighter binding. "

Around here we tend to use the official C standard, rather than MS
mis-interpretations.
 
B

bjarne

"The order of evaluation of subexpressions within an expression is
undefined." - Bjarne Stroustrup, "The C++ Programming Language",
Special Edition, January 2000.

Mr Stroustrup appears to disagree with Mr Stroustrup. Here in
comp.lang.c we cannot possibly countenance judging between the opinions
of these two C++ masters, so I must refer you to comp.lang.c++, where
you may well find that either Mr Stroustrup or Mr Stroustrup will be
able to clarify.
:)

(To be belatedly fair to Bjarne Stroustrup, something rather important
and dramatic happened to C++ between 1991 and 1998.)

Indeed, but the standardization only clarified that part of the text,
rather than changing the rules. The full quote is/was

The order of evaluation of subexpressions is determined by the
precedence and grouping of
the operators. The usual mathematical rules for associativity and
commutativity of operators
may be applied only where the operators really are associative and
commutative. Except
where noted, the order of evaluation of operands of individual
operators is undefined. In
particular, if a value is modified twice in an expression, the
result of the expression is
undefined except where an ordering is guaranteed by the operators
involved. For example:
i = v [i++; ] // the value of 'i8 is undefined
i-7, i++i+,+ ; // 'it becomes 9

I was (I think and rather unsuccessfully) trying to distinguish
between the effect of the grouping and precedence rules (as in (x*y)/z
v.s. x*(y/z)) on the meaning of an expression and the order of
evaluations rules.

Except where noted, the order of evaluation of operands of
individual operators is undefined.

Makes clear that there was no C/C++ incompatibility in this case
("except where noted" refers to the text for ||, &&, and comma). I
don't recall this as a significant problem for users and none for
implementers.

It is always hazardous to cut part of a paragraph out of context.

-- Bjarne Stroustrup; http://www.research.att.com/~bs
 
B

Barry Schwarz

I think that this is misleading. d+e should not be evaluated at all.

additive-expression:
multiplicative-expression
additive-expression + multiplicative-expression
additive-expression - multiplicative-expression

d+e is an additive expression, not a multiplicative-expression so
can't form the right hand side of an additive expression.

Would it make you happier if the code were written
a = d + e + b * c;

The point remains unchanged. There is no guarantee that b*c will be
evaluated first, which is what the OP wanted to claim.


Remove del for email
 
C

Charles Bailey

Would it make you happier if the code were written
a = d + e + b * c;

The point remains unchanged. There is no guarantee that b*c will be
evaluated first, which is what the OP wanted to claim.

Yes, in that I think that this is a much better example. Both d + e
and b * c are constituent sub-expressions of the overall expression
and so both do have to be evaluated. There is no reason, either in
the C standard or - as succinctly put in a previous thread on this
subject - in reality, for either to be evaluated before the other.
 
R

Rasjid

Unless this is a MSVC++##4.0 manual, and not a C Reference Manual as
such, that is simply a lie.


Oh, I should hope so. It's wrong. Of course, it's Microsoft, so no
surprise there; they always insist that their way is the only way, and
industry standards exist so they can break them.
I think I learn something , that little knowledge hurts. There is C
and there is C.
We have to know what we're reading.

BTW, I think hordes of DIY programmers ( like me) out there think in a
* b + c, that things got multiplied before added, other things
ignored!

Thanks,
Rasjid
 
R

Rasjid

Indeed, but the standardization only clarified that part of the text,
rather than changing the rules. The full quote is/was

The order of evaluation of subexpressions is determined by the
precedence and grouping of the operators. The usual ...

A reference manual that implements a language standard should be as
simple
as is possible. If anything is discovered that is superfluous it
should be eliminated.

Order of evaluation is a critical matter in the execution of codes and
may be a complicated issue. There is order of application of operators
on operands as well as order of evaluation of operands. What have been
written so far here seem to suggest there is almost no connection
between precedence of operators and order of evaluation of
subexpressions. I asked for any instance where there is a need to
invoke operator precedence/order rule to resolve things and no one
seem to be able to provide a single example. So it seems any mention
of any connection of precedence of operators with order of evaluation
serves no purpose at all and only causes confusion to unsuspecting
users (potentially many). If the said connection is actually needed in
the C standard, it may be for very rare instances which may be better
settled in other manner that do not cause confusion.

Rasjid
 
A

Army1987

Rasjid said:
A reference manual that implements a language standard should be as
simple
as is possible. If anything is discovered that is superfluous it
should be eliminated.

Order of evaluation is a critical matter in the execution of codes and
may be a complicated issue. There is order of application of operators
on operands as well as order of evaluation of operands. What have been
written so far here seem to suggest there is almost no connection
between precedence of operators and order of evaluation of
subexpressions. I asked for any instance where there is a need to
invoke operator precedence/order rule to resolve things and no one
seem to be able to provide a single example. So it seems any mention
of any connection of precedence of operators with order of evaluation
serves no purpose at all and only causes confusion to unsuspecting
users (potentially many). If the said connection is actually needed in
the C standard, it may be for very rare instances which may be better
settled in other manner that do not cause confusion.

a = b * c;

a will (of course) be assigned after both b and c are evaluated.
f(a(x) + b(y));

x will have to be evaluated before a(), y before b(), and f() after
both a and b, of course. But any of the orders
x, y, a(), b(), f() or
x, y, b(), a(), f() or
x, a(), y, b(), f() or
y, x, a(), b(), f() or
y, x, b(), a(), f() or
y, b(), x, a(), f() (am I missing some?) are allowed.
 
R

Richard Heathfield

Rasjid said:

Order of evaluation is a critical matter in the execution of codes

No, it isn't. Or at least, if it is, your code needs rewriting until it
isn't.
 
H

Harald van =?UTF-8?B?RMSzaw==?=

Richard said:
Rasjid said:



No, it isn't. Or at least, if it is, your code needs rewriting until it
isn't.

Okay, how would you then rewrite

if (p != NULL && p->data == 1234) {
/* A */
} else {
/* B */
}

? Would you prefer

if (p != NULL) {
if (p->data == 1234) {
/* A */
} else {
/* B */
}
} else {
/* B */
}

or would you rather see something like

if (p != NULL) {
if (p->data != 1234)
goto Else;
/* A */
} else {
Else:
/* B */
}

to avoid unnecessary code duplication?
 
R

Rasjid

a = b * c;

a will (of course) be assigned after both b and c are evaluated.
f(a(x) + b(y));

x will have to be evaluated before a(), y before b(), and f() after
both a and b, of course. But any of the orders
x, y, a(), b(), f() or
x, y, b(), a(), f() or
x, a(), y, b(), f() or
y, x, a(), b(), f() or
y, x, b(), a(), f() or
y, b(), x, a(), f() (am I missing some?) are allowed.
It is I who is missing something!
In your example, if I don't know any connection between precedence of
operators and order of evaluation, does it matter?

Rasjid
 
R

Richard Heathfield

Harald van D?k said:
Okay, how would you then rewrite

if (p != NULL && p->data == 1234) {

Do you mind, Harald? I was *talking*.

As I was ABOUT TO SAY... We can make an exception for guaranteed
evaluation-order-enforcing constructs such as &&, ||, the comma
operator, and so on.

Now then, do I think I've managed to weasel my way out of that?

Er... no.
 
A

Army1987

Rasjid said:
It is I who is missing something!
In your example, if I don't know any connection between precedence of
operators and order of evaluation, does it matter?

Rasjid
No. It doesn't. At least, you won't get confused.

Operands can be evaluated at any time.
But obviously they must be evaluated before they are needed. In the
example above, f() has to know the value of its argument, and + has
to know the value of its operands.
 
C

Chris Dollin

Richard said:
Rasjid said:



No, it isn't.

It certainly is: it's /the/ defining characteristic of the imperative
languages, where part of the skill is arranging that the order things
happen in gets the results you want.
Or at least, if it is, your code needs rewriting until it
isn't.

That applies to order-of-evaluation-of-/operands-in-most-expressions/.

[Where it's still critical, as in, we'll be critical of code that
tries it except for the well-defined cases, and maybe even then,
for sanity.]
 
R

Richard Heathfield

Chris Dollin said:
It certainly is:

No, it isn't.
it's /the/ defining characteristic of the imperative
languages, where part of the skill is arranging that the order things
happen in gets the results you want.

Ah, you're changing the terms of the discussion. Clearly we were
discussing order of evaluation between two consecutive sequence points.
Now you're widening the discussion somewhat, to the idea of sequence in
general, but that's probably a waste of time, insofar as nobody will
bother to argue with you about it.

<snip>
 
B

Barry Schwarz

I think I learn something , that little knowledge hurts. There is C
and there is C.
We have to know what we're reading.

BTW, I think hordes of DIY programmers ( like me) out there think in a
* b + c, that things got multiplied before added, other things
ignored!

In that particular case it is true. The point is in general it need
not be.


Remove del for email
 
B

Barry Schwarz

A reference manual that implements a language standard should be as
simple
as is possible. If anything is discovered that is superfluous it
should be eliminated.

That depends on whether the manual is intended to have any educational
value. Repetition, examples, and alternate expositions can be
valuable.
Order of evaluation is a critical matter in the execution of codes and

Except for the few operators with implied or explicit sequence points,
it should not be. If it is, what are you going to do when the next
upgrade to the compiler changes the order? In fact, most places where
people think it matters are actually prohibited as undefined behavior.
may be a complicated issue. There is order of application of operators

Lack of understanding can make the simplest things appear complicated.
on operands as well as order of evaluation of operands. What have been

The only thing you know for certain is that the operands of an
operator will be evaluated prior to the operator being applied to
them.
written so far here seem to suggest there is almost no connection
between precedence of operators and order of evaluation of
subexpressions. I asked for any instance where there is a need to
invoke operator precedence/order rule to resolve things and no one
seem to be able to provide a single example. So it seems any mention

I can't tell if I've seen all the messages in this thread but I don't
remember any such request. However, the typical example of a strcpy
work-alike provides an example:
char * my_copy(char *dest, const char *src)
{char *rtn = dest;
while (*dest++ = *src++;)
;
return rtn;}

Is the ++ applied to the pointer or the object pointed to? If you
don't know the precedence and associativity of the operators, how
would you figure it out?
of any connection of precedence of operators with order of evaluation
serves no purpose at all and only causes confusion to unsuspecting
users (potentially many). If the said connection is actually needed in
the C standard, it may be for very rare instances which may be better
settled in other manner that do not cause confusion.



Remove del for email
 
K

Keith Thompson

Rasjid said:
Thanks, I test if it works
Why no preview for reply?

If your reply is just plain text, you don't need a preview.

If your reply isn't just plain text, please don't post it here.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top