C/C++ Ambiguity in Order of Evaluation

R

Rasjid

Hello,

I have just joined and this is my first post.

I have never been able to resolve the issue of order of evaluation in
C/C++ and the related issue of precedence of operators, use of
parentheses.
From the reference manual I have :-
1) "The order of evaluation of subexpressions is determined by the
precedence and grouping of operators."
2) order of evaluation of operands of operators undefined except where
noted.

I was just told at another forum that
v = u - ((u & -(u = 1)) << 1);
has undefined behavior and the reason given was
the order of evaluation of operands u, -(u = 1) of & is undefined.
That unary - has the highest precedence or the use of parentheses in -
(u = 1) is of no consequence.

Also all over the internet, the impression I get about
x = a * b + c;
is that the order of evaluation is a * b, ? + c, x = ?
But the order(undefined) of evaluation may be (c) , a * b,
x = ? + ?

The same person seem to say unequivocally (?) that precedence
of operators has nothing to do with order of evaluation, but only
about binding operands to operators.

So I have the following questions :-
1) v = u - ((u & -(u = 1)) << 1); Is this undefined and why?
2) Does precedence of operators determine order of evaluation ? If
Yes, then in what situations.
3) If answer to 2) is No, then how is C affected if precedence of
operators is redefined in sort of this manner :-
"precedence of operators determines the grouping of operands with
operators" - without any reference to order of evaluation.

Best Regards,
Rasjid
 
R

Richard Heathfield

Rasjid said:
Hello,

I have just joined and this is my first post.

Welcome to comp.lang.c.
I have never been able to resolve the issue of order of evaluation in
C/C++

The language we discuss here is called C. The C++ language is discussed
in comp.lang.c++. Information about C that you learn here may, or may
not, apply to C++ as well.
and the related issue of precedence of operators, use of
parentheses.

Precedence has little or nothing to do with order of evaluation.
1) "The order of evaluation of subexpressions is determined by the
precedence and grouping of operators."

That's false. For example, consider:

#include <stdio.h>

int f(void) { printf("Hi! I'm f()\n"); return 2; }
int g(void) { printf("Hi! I'm g()\n"); return 3; }
int h(void) { printf("Hi! I'm h()\n"); return 4; }

int main(void)
{
printf("The result is %d.\n", f() + g() * h());
return 0;
}

If your reference manual were correct, g() and h() would be evaluated
before f(). But on my system, the output is:

Hi! I'm f()
Hi! I'm g()
Hi! I'm h()
The result is 14.

which suggests that f() is evaluated first.
2) order of evaluation of operands of operators undefined except where
noted.

In fact, the order of evaluation is unspecified rather than undefined.
That means that there /is/ an order of evaluation, but that order is
entirely up to the implementation.
I was just told at another forum that
v = u - ((u & -(u = 1)) << 1);
has undefined behavior and the reason given was
the order of evaluation of operands u, -(u = 1) of & is undefined.
That unary - has the highest precedence or the use of parentheses in -
(u = 1) is of no consequence.

The reason the expression is undefined is that it violates a "shall"
clause of the C Standard that is not a constraint:

"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."
Also all over the internet, the impression I get about
x = a * b + c;
is that the order of evaluation is a * b, ? + c, x = ?

Nope. It's up to the implementation, and implementations can and do vary
in this respect.
But the order(undefined) of evaluation may be (c) , a * b,
x = ? + ?

The same person seem to say unequivocally (?) that precedence
of operators has nothing to do with order of evaluation, but only
about binding operands to operators.

Absolutely right. The only connection is that in some cases a given
precedence will make it almost impossible to find more than one order
of evaluation that makes sense, but this is of no consequence as far as
the programmer is concerned. See my f() g() h() example (above). The
only safe assumption you can make is that there is no connection
whatsoever between precedence (or indeed associativity) and evaluation
order.
So I have the following questions :-
1) v = u - ((u & -(u = 1)) << 1); Is this undefined and why?

Yes, it's undefined, because it violates a "shall" that is not within a
constraint. (If it were within a constraint, it would still be
undefined, but it would also require a diagnostic message.)
2) Does precedence of operators determine order of evaluation ? If
Yes, then in what situations.

No, it doesn't, except accidentally. For example, it's hard to come up
with an order of evaluation for x * y + z that doesn't do the
multiplication before it does the addition. Nevertheless, even there,
as my earlier example showed, the order of evaluation of the operands
is anyone's guess.
3) If answer to 2) is No, then how is C affected if precedence of
operators is redefined in sort of this manner :-
"precedence of operators determines the grouping of operands with
operators" - without any reference to order of evaluation.

This affects C not at all, since it already works like that.
 
R

Richard Bos

Rasjid said:
I have never been able to resolve the issue of order of evaluation in
C/C++

There's no such thing as C/C++. There's C, and there's C++, and in some
areas they are the same, in some they're obviously different, and in
some they're subtly but significantly different. I have no idea which
part your question falls in; I'll answer it for C.
and the related issue of precedence of operators, use of parentheses.

1) "The order of evaluation of subexpressions is determined by the
precedence and grouping of operators."

This is not true.
2) order of evaluation of operands of operators undefined except where
noted.

This is true.
I was just told at another forum that
v = u - ((u & -(u = 1)) << 1);
has undefined behavior and the reason given was
the order of evaluation of operands u, -(u = 1) of & is undefined.

It does have undefined behaviour, but the order of evaluation has
nothing to do with it. You are modifying u in that expression (in the
sub-expression u = 1), and you are also using the value of u for a
reason not directly necessary for that modification (the other two u's).
Doing so invokes UB. If you modify any object, all other references to
that same object between the two surrounding sequence points must be for
the purpose of determining the new value.
Also all over the internet, the impression I get about
x = a * b + c;
is that the order of evaluation is a * b, ? + c, x = ?

Wrong. Or rather, not guaranteed.
But the order(undefined) of evaluation may be (c) , a * b,
x = ? + ?

May be. Or it may be b, c, a, multiplication, addition.
The same person seem to say unequivocally (?) that precedence
of operators has nothing to do with order of evaluation, but only
about binding operands to operators.

Yes, that is true.
So I have the following questions :-
1) v = u - ((u & -(u = 1)) << 1); Is this undefined and why?

Undefined, but for a different reason; see above.
2) Does precedence of operators determine order of evaluation ?

No. Except for a few special operators: &&, ||, ?: and comma.

Actually, C operators don't have precedence as such. How strongly they
bind relative to which other operators, and in which direction, is
determined by the grammar, not by a precedence table. The result is the
same, though - the order of evaluation of sub-expressions in C is only
determined by two things:
1. obviously, sub-expressions must be evaluated before their containing
larger expressions (but not necessarily before any other sub-
expression of that or any other larger expression);
2. some points in a C program are sequence points, and all expressions
before a sequence point shall be evaluated before all expressions
after it. Sequence points include the end of an expression statement
and the call of a function, but also the operators above.
3) If answer to 2) is No, then how is C affected if precedence of
operators is redefined in sort of this manner :-
"precedence of operators determines the grouping of operands with
operators" - without any reference to order of evaluation.

Explain "grouping".

Richard
 
A

Army1987

Rasjid said:
Hello,

I have just joined and this is my first post.

I have never been able to resolve the issue of order of evaluation in
C/C++ and the related issue of precedence of operators, use of
parentheses.

1) "The order of evaluation of subexpressions is determined by the
precedence and grouping of operators."
2) order of evaluation of operands of operators undefined except where
noted.

I was just told at another forum that
v = u - ((u & -(u = 1)) << 1);
has undefined behavior and the reason given was
the order of evaluation of operands u, -(u = 1) of & is undefined.
That unary - has the highest precedence or the use of parentheses in -
(u = 1) is of no consequence.

Also all over the internet, the impression I get about
x = a * b + c;
is that the order of evaluation is a * b, ? + c, x = ?
But the order(undefined) of evaluation may be (c) , a * b,
x = ? + ?

x = a * b + c
can work as

t1 = a; t2 = b; t3 = c; t4 = t1 * t2; t5 = t4 * t3; x = t5;

or any reshuffling of these. The only requirement is (of course)
that t4 gets assigned after both t1 and t2 do, t5 gets assigned
after t4 and t3 do, and x is assigned after t5. Any other
reordering is allowed.
 
C

Chris Dollin

Rasjid said:
I have just joined and this is my first post.

Note that comp.lang.c is a newsgroup -- there's no real notion
of "joining". Post as you will; read as you will. Just remember
that the order /you/ see posts in need not be the same as the
order /we/ see them in.
I have never been able to resolve the issue of order of evaluation in
C/C++

Note that here we do C, not C++. I suspect that their behaviour
is much the same in this respect -- but I don't /know/. You'll
have to ask in comp.lang.c++ to get the details for that language.
and the related issue of precedence of operators, use of
parentheses.

The /very slightly/ related. A useful rule of thumb is to
pretend they're not related at all.

"The" reference manual? What manual, what page?
1) "The order of evaluation of subexpressions is determined by the
precedence and grouping of operators."

It isn't, except in the sense that "precedence and grouping" -- ie the
grammar of expressions -- says what's an operand of what operation, and
in general an operation can't be evaluated until all its operands
have been. (There are specific exceptions.)
2) order of evaluation of operands of operators undefined except where
noted.
Indeed.

I was just told at another forum that
v = u - ((u & -(u = 1)) << 1);
Ulgh.

has undefined behavior

Indeed. (Assuming suitable declarations, and all that.)
and the reason given was
the order of evaluation of operands u, -(u = 1) of & is undefined.

Specifically, it's undefined behaviour if an object that is updated
in an expression is read from for any other reason than to determine
its new value (before the next sequence point). Here, `u` is read
from as one operand of the `&`.
That unary - has the highest precedence or the use of parentheses in -
(u = 1) is of no consequence.

It's certainly of consequence: if it were `... -u = 1 ...` it would
be illegal; `-u` isn't an assignable expression.
Also all over the internet,

/All/? You've been everywhere, man?
the impression I get about
x = a * b + c;
is that the order of evaluation is a * b, ? + c, x = ?

No.

`a`, `b`, `c`, and the address of `x` can be evaluated in any
convenient order. The multiplication "has" (for pretty strong
values of "has") to be done before the addition, and the
addition "has" to be done before the assignment -- but in a
C program you don't get to see the multiplication, addition,
and assignment happening.

[(fx:OT) In C++, where the + and * and = might be overloaded
and implemented by functions, you /can/ see this ordering.
But C is not C++.]
But the order(undefined) of evaluation may be (c) , a * b,
x = ? + ?
Yes.

The same person seem to say unequivocally (?) that precedence
of operators has nothing to do with order of evaluation, but only
about binding operands to operators.

Yes. Almost nothing -- because of the "operands before operations"
ordering, but that's not what people are usually talking about.
So I have the following questions :-
1) v = u - ((u & -(u = 1)) << 1); Is this undefined and why?

Undefined, as above.
2) Does precedence of operators determine order of evaluation ?
No.

If Yes, then in what situations.
3) If answer to 2) is No, then how is C affected if precedence of
operators is redefined in sort of this manner :-
"precedence of operators determines the grouping of operands with
operators" - without any reference to order of evaluation.

I don't know what you mean. Precedence is just shorthand for
grammar rules, which in turn tell you for things like

a + b * c

which operand is bound to which operator. (Or at least, what
the parse tree looks like.)
 
R

Rasjid

Rasjid said:

Precedence has little or nothing to do with order of evaluation.
It's from Bjarne Stroustrup C++ ..., Reference Manual of C++ as of May
1991.
That's false. For example, consider:...

I've no choice but to dismiss that part of the manual as I don't know
what it is there for. Can someone tell if the later version of the
official C & C++ ( I don't own a copy ) still has references to order
of evaluation when it mentions precedence of operators.

K&R very early mentioned that C, as in other languages, left the order
of evaluation of operands undefined (had ... been the copy writer in
charge of the drafting, he / she would have recommended "unspecified"
instead) intentionally.
The reason being some machine architecture may benefit from a certain
order of evaluations.

So after a long long time my confusion is resolved, but only by
throwing away the official document (that seems only to confuse) -
that's bad.
The reason the expression is undefined is that it violates a "shall"
clause of the C Standard that is not a constraint:

"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."

This is beautiful! I can understand the official(?) document.
My unofficial version is something like :-
"However, the value of a scalar object may be modified no more than
once between any two consecutive sequence points. If it is modified,
use of the prior value is restricted and may only be used in
determining what new value is to be stored." Walter E. Brown 1999.

Now that I've been set free (The Truth shalt set you free ... Discard
the canon of untruth ), an attempt to be intelligent is in order. It
is like only such is ok :-
a = b * (c = c + 1);
a = c + b * (c = 2007);//UB

Absolutely right. The only connection is that in some cases a given
precedence will make it almost impossible to find more than one order
of evaluation that makes sense, but this is of no consequence as far as
the programmer is concerned. See my f() g() h() example (above). The
only safe assumption you can make is that there is no connection
whatsoever between precedence (or indeed associativity) and evaluation
order.
You're decisive.
Ok I accept the Chris Dollin Rule of Thumb - Zero connection

Yes, it's undefined, because it violates a "shall" that is not within a
constraint. (If it were within a constraint, it would still be
undefined, but it would also require a diagnostic message.)


No, it doesn't, except accidentally. For example, it's hard to come up
with an order of evaluation for x * y + z that doesn't do the
multiplication before it does the addition. Nevertheless, even there,
as my earlier example showed, the order of evaluation of the operands
is anyone's guess.

Life is too easy, I'll suggest changes to C spec... precedence of
operators determines evaluation of OPERATORS but
operands...unspecified... and in situation where there is no way
out...that's easy...
This affects C not at all, since it already works like that.

Send a petition that you be seated on the RHS of the Chairperson of
the ANSI C committee...
 
R

Rasjid


The 4 replies basically is in agreement and my main comments is in my
reply to
Richard Heathfield.

I think my problem is resolved. It seems I was in some way misled. Had
there
be no mentioned of order of evaluations etc, then everyone would have
been careful when trying such as:-
a = b + (b = 1);

Thanks
Rasjid
 
R

Richard Heathfield

Rasjid said:
It's from Bjarne Stroustrup C++ ..., Reference Manual of C++ as of May
1991.

"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.)

I've no choice but to dismiss that part of the manual as I don't know
what it is there for. Can someone tell if the later version of the
official C & C++ ( I don't own a copy ) still has references to order
of evaluation when it mentions precedence of operators.

"Except as indicated by the syntax or otherwise specified later
(for the function-call operator () , && , || , ?: , and comma
operators), the order of evaluation of subexpressions and the order in
which side effects take place are both unspecified."
K&R very early mentioned that C, as in other languages, left the order
of evaluation of operands undefined (had ... been the copy writer in
charge of the drafting, he / she would have recommended "unspecified"
instead) intentionally.

"C, like most languages, does not specify the order in which the
operands of an operator are evaluated." - K&R2, p52
"Similarly, the order in which function arguments are evaluated is not
specified" - K&R2, p53
The reason being some machine architecture may benefit from a certain
order of evaluations.
Whatever.

So after a long long time my confusion is resolved, but only by
throwing away the official document (that seems only to confuse) -
that's bad.

No, your official C++ document stopped being official almost a decade
ago. It was replaced by ISO/IEC 14882:1998 (which, I believe, has since
been replaced by an update). Here in comp.lang.c we use ISO/IEC
9899:1990 or ISO/IEC 9899:1999, depending on who you talk to.

This is beautiful! I can understand the official(?) document.
My unofficial version is something like :-
"However, the value of a scalar object may be modified no more than
once between any two consecutive sequence points. If it is modified,
use of the prior value is restricted and may only be used in
determining what new value is to be stored." Walter E. Brown 1999.

I'm not convinced that that's an accurate re-wording.
Now that I've been set free (The Truth shalt set you free ... Discard
the canon of untruth ), an attempt to be intelligent is in order. It
is like only such is ok :-
a = b * (c = c + 1);

That looks okay to me. Nothing gets modified more than once, and c's
prior value is used only to determine the value to be stored.
Nevertheless, the expression sucks.
a = c + b * (c = 2007);//UB

I think I agree with you, although I'm not a great fan of these academic
exercises, to be honest, and we could both be wrong. Like the other
expression, this one sucks, and should be split into at least two.

You're decisive.

Sometimes I'm not so sure about that.
Ok I accept the Chris Dollin Rule of Thumb - Zero connection

Chris, you pinched that off me, you son of a puppy...

Life is too easy, I'll suggest changes to C spec... precedence of
operators determines evaluation of OPERATORS but
operands...unspecified...

Operators are never evaluated. They are active, not passive. "An
operator specifies an operation to be performed (an evaluation) that
yields a value, or yields a designator, or produces a side effect, or a
combination thereof. An operand is an entity on which an operator
acts."
 
R

Rasjid

Note that comp.lang.c is a newsgroup -- there's no real notion
of "joining". Post as you will; read as you will. Just remember
that the order /you/ see posts in need not be the same as the
order /we/ see them in.


Note that here we do C, not C++. I suspect that their behaviour
is much the same in this respect -- but I don't /know/. You'll
have to ask in comp.lang.c++ to get the details for that language.


The /very slightly/ related. A useful rule of thumb is to
pretend they're not related at all.


"The" reference manual? What manual, what page?
Please see my other reply.
It isn't, except in the sense that "precedence and grouping" -- ie the
grammar of expressions -- says what's an operand of what operation, and
in general an operation can't be evaluated until all its operands
have been. (There are specific exceptions.)

I'll just simplify things and use the Zero Connection Rule. Compare
the specs quoted by R. Heathfield, perfectly clear without any need to
speculate on wording subtleties.

Thanks
Rasjid
2) order of evaluation of operands of operators undefined except where
noted.
Indeed.

I was just told at another forum that
v = u - ((u & -(u = 1)) << 1);
Ulgh.

has undefined behavior

Indeed. (Assuming suitable declarations, and all that.)
and the reason given was
the order of evaluation of operands u, -(u = 1) of & is undefined.

Specifically, it's undefined behaviour if an object that is updated
in an expression is read from for any other reason than to determine
its new value (before the next sequence point). Here, `u` is read
from as one operand of the `&`.
That unary - has the highest precedence or the use of parentheses in -
(u = 1) is of no consequence.

It's certainly of consequence: if it were `... -u = 1 ...` it would
be illegal; `-u` isn't an assignable expression.
Also all over the internet,

/All/? You've been everywhere, man?
the impression I get about
x = a * b + c;
is that the order of evaluation is a * b, ? + c, x = ?

No.

`a`, `b`, `c`, and the address of `x` can be evaluated in any
convenient order. The multiplication "has" (for pretty strong
values of "has") to be done before the addition, and the
addition "has" to be done before the assignment -- but in a
C program you don't get to see the multiplication, addition,
and assignment happening.

[(fx:OT) In C++, where the + and * and = might be overloaded
and implemented by functions, you /can/ see this ordering.
But C is not C++.]
But the order(undefined) of evaluation may be (c) , a * b,
x = ? + ?
Yes.

The same person seem to say unequivocally (?) that precedence
of operators has nothing to do with order of evaluation, but only
about binding operands to operators.

Yes. Almost nothing -- because of the "operands before operations"
ordering, but that's not what people are usually talking about.
So I have the following questions :-
1) v = u - ((u & -(u = 1)) << 1); Is this undefined and why?

Undefined, as above.
2) Does precedence of operators determine order of evaluation ?
No.

If Yes, then in what situations.
3) If answer to 2) is No, then how is C affected if precedence of
operators is redefined in sort of this manner :-
"precedence of operators determines the grouping of operands with
operators" - without any reference to order of evaluation.

I don't know what you mean. Precedence is just shorthand for
grammar rules, which in turn tell you for things like

a + b * c

which operand is bound to which operator. (Or at least, what
the parse tree looks like.)
 
F

Flash Gordon

Rasjid wrote, On 20/06/07 18:55:

I've no choice but to dismiss that part of the manual as I don't know
what it is there for. Can someone tell if the later version of the
official C & C++ ( I don't own a copy ) still has references to order
of evaluation when it mentions precedence of operators.

Stroutrup is not, and never has been, official documentation for C.
Since C++ was standardised it has not been offcial documentation for C++
either.

K&R has not been official documentation for C since the standard was
first published by ANSI in 1989 and adopted a year later (for the
international community) by ISO.
> very early mentioned that C, as in other languages, left the order
of evaluation of operands undefined (had ... been the copy writer in
charge of the drafting, he / she would have recommended "unspecified"
instead) intentionally.

<snip>

Not in K&R1 since at that time neither undefined not unspecified was
defined.
 
F

Flash Gordon

Richard Heathfield wrote, On 20/06/07 12:14:
Rasjid said:


In fact, the order of evaluation is unspecified rather than undefined.
That means that there /is/ an order of evaluation, but that order is
entirely up to the implementation.

<snip>

Note to the OP (Richard knows this I'm sure): The implementation does
not have to document the order and it could even change from one run of
the program to the next.
 
R

Richard Heathfield

Flash Gordon said:
Richard Heathfield wrote, On 20/06/07 12:14:

<snip>

Note to the OP (Richard knows this I'm sure): The implementation does
not have to document the order and it could even change from one run
of the program to the next.

Thanks, Flash - yes, I did indeed know that, and I ought to have
mentioned it to the OP.
 
A

Army1987

Richard Heathfield said:
Rasjid said:

I think I agree with you, although I'm not a great fan of these academic
exercises, to be honest, and we could both be wrong.

If you were wrong, and b and c were both 1 at the previous sequence
point, who would decide wheter a becomes 2008 or 4014?
 
C

CBFalconer

Rasjid said:
.... snip ...

The 4 replies basically is in agreement and my main comments is
in my reply to Richard Heathfield.

I think my problem is resolved. It seems I was in some way misled.
Had there be no mentioned of order of evaluations etc, then
everyone would have been careful when trying such as:-
a = b + (b = 1);

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).

Please do not top-post. Your answer belongs after (or intermixed
with) the quoted material to which you reply, after snipping all
irrelevant material. See the following links:

--
<http://www.catb.org/~esr/faqs/smart-questions.html>
<http://www.caliburn.nl/topposting.html>
<http://www.netmeister.org/news/learn2quote.html>
<http://cfaj.freeshell.org/google/> (taming google)
<http://members.fortunecity.com/nnqweb/> (newusers)
 
R

Rasjid

Please do not top-post. Your answer belongs after (or intermixed
with) the quoted material to which you reply, after snipping all
irrelevant material. See the following links:

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

Rasjid
 
R

Rasjid

"Except as indicated by the syntax or otherwise specified later
(for the function-call operator () , && , || , ?: , and comma
operators), the order of evaluation of subexpressions and the order in
which side effects take place are both unspecified."

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. "

I am not sure if anyone take issue with the paragraph. Or is the
paragraph necessary? I have to acknowledge I try to be fast. If
someone learns comprehensively and covers and understands every
topics, then there is no problem after. But what about someone who
just wants to check only on order of evaluation when attempting
v = u & -(u = 1);
Is it certain that unary - will first be evaluated ? Yes, highest
precedence !
Maybe this is better:-
"Expressions with higher-precedence operators are evaluated first
assuming all relevant operands have been evaluated as they may be
evaluated in any order."

No, your official C++ document stopped being official almost a decade
ago. It was replaced by ISO/IEC 14882:1998 (which, I believe, has since
been replaced by an update). Here in comp.lang.c we use ISO/IEC
9899:1990 or ISO/IEC 9899:1999, depending on who you talk to.

I some parts or niches of the world, information takes 40 years to get
through.
Nevertheless, the expression sucks.
..this one sucks, ....

Beauty is in the eyes of the beholden!

I am from a chess programming forum. We write only for ourselves and
for the fastest codes. The original format is more like:-
If ( exprA && (w = (u - ((u & -(u = bitboard1 | bitboard2)) << 1))) ){
}
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)))) ){
}
that's what the comma is for.

Best Regards,
Rasjid
 
B

Barry Schwarz

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. "

Microsoft doesn't write the standard. This may describe how their
compilers work but has nothing to do with this newsgroup. If you want
a Microsoft specific discussion, go to one of the newsgroups that
deals with their compilers.
I am not sure if anyone take issue with the paragraph. Or is the
paragraph necessary? I have to acknowledge I try to be fast. If
someone learns comprehensively and covers and understands every
topics, then there is no problem after. But what about someone who
just wants to check only on order of evaluation when attempting
v = u & -(u = 1);
Is it certain that unary - will first be evaluated ? Yes, highest
precedence !

Since your statement invokes undefined behavior, any discussion of
order of evaluation is meaningless. And if you change the second u to
x, you still don't know. The only thing you know for certain is that
both u and -(x=1) will both be evaluated before the & operator is
applied.

BTW, the unary - cannot be evaluated first. The expression x=1 must
be evaluated before the unary - can be evaluated.
Maybe this is better:-
"Expressions with higher-precedence operators are evaluated first
assuming all relevant operands have been evaluated as they may be
evaluated in any order."

Still not true. Consider
a = b * c + d + e;
Multiplication is the highest precedence but it is still legal for d+e
to be evaluated prior to a*b. If d+e is a common expression, it may
have been evaluated in a previous statement and not recomputed here.

snip
Beauty is in the eyes of the beholden!

But behavior is defined by the standard.
I am from a chess programming forum. We write only for ourselves and
for the fastest codes. The original format is more like:-
If ( exprA && (w = (u - ((u & -(u = bitboard1 | bitboard2)) << 1))) ){
}
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)))) ){
}
that's what the comma is for.

Why do you think the expression u & -u produces the same result on all
systems? Not everyone uses twos complement.


Remove del for email
 
A

Army1987

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. 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. "

I am not sure if anyone take issue with the paragraph. Or is the
paragraph necessary? I have to acknowledge I try to be fast. If
someone learns comprehensively and covers and understands every
topics, then there is no problem after. But what about someone who
just wants to check only on order of evaluation when attempting
v = u & -(u = 1);
Is it certain that unary - will first be evaluated ? Yes, highest
precedence !
Maybe this is better:-
"Expressions with higher-precedence operators are evaluated first
assuming all relevant operands have been evaluated as they may be
evaluated in any order."
The C programming language standard does not require that every
implementation works the same as Microsoft's.
 
C

Chris Dollin

Richard said:
Rasjid said:


Chris, you pinched that off me, you son of a puppy...

Not quite -- since mine's a rule-of-thumb, not an Absolute. But I will
happily give you credits. (I keep them in a jar with my spare smilies.)
Operators are never evaluated. They are active, not passive. "An
operator specifies an operation to be performed (an evaluation) that
yields a value, or yields a designator, or produces a side effect, or a
combination thereof. An operand is an entity on which an operator
acts."

(fx:OT) In C++ -- which Rasjid was also asking about -- I wouldn't
say that, since operators may be implemented with user-defined functions.
Even if you can't see the evaluation of the operator function [I can't
remember whether they can be instance methods or they have to be static],
you /can/ see the act of applying the operation to the operands: stuff
a printf or equivalent in the function body.
 
C

Charles Bailey

Still not true. Consider
a = b * c + d + e;
Multiplication is the highest precedence but it is still legal for d+e
to be evaluated prior to a*b. If d+e is a common expression, it may
have been evaluated in a previous statement and not recomputed here.

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.

The expression a = b * c + d + e can only parse as equivalent to:
a = (((b * c) + d) + e)
it is not equivalent to:
a = ((b * c) + (d + e))

The only exception is of the implementation determines that it does't
matter under an "as if" decision, but then it's academic anyway.
 

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

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top