449,438 Members | 1,610 Online
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,438 IT Pros & Developers. It's quick & easy.

# C/C++ Ambiguity in Order of Evaluation

 P: n/a 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 Jun 20 '07 #1
54 Replies

 P: n/a 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. >>From the reference manual I have :- 1) "The order of evaluation of subexpressions is determined by the precedence and grouping of operators." That's false. For example, consider: #include 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. -- Richard Heathfield "Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk email: rjh at the above domain, - www. Jun 20 '07 #2

 P: n/a Rasjid

 P: n/a "Rasjid" >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 = ? + ? 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. Jun 20 '07 #4

 P: n/a On Jun 20, 7:14 pm, Richard Heathfield From the reference manual I have :- 1) "The order of evaluation of subexpressions is determined by the precedence and grouping of operators." 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. 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." 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 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. You're decisive. Ok I accept the Chris Dollin Rule of Thumb - Zero connection > 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. 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... > 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. Send a petition that you be seated on the RHS of the Chairperson of the ANSI C committee... > -- Richard Heathfield "Usenet is a strange place" - dmr 29/7/1999http://www.cpax.org.uk email: rjh at the above domain, - www. Jun 20 '07 #6

 P: n/a On Jun 20, 7:15 pm, r...@hoekstra-uitgeverij.nl (Richard Bos) wrote: Rasjid From the reference manual I have :- 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 Jun 20 '07 #7

 P: n/a Rasjid said: On Jun 20, 7:14 pm, Richard Heathfield Rasjid said: I have never been able to resolve the issue of order of evaluation in C/C++ Precedence has little or nothing to do with order of evaluation. >>From the reference manual I have :- 1) "The order of evaluation of subexpressions is determined by the precedence and grouping of operators." 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.) >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. "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. >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 haveits stored value modified at most once by the evaluation of anexpression. Furthermore, the prior value shall be accessed only todetermine 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. 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." -- Richard Heathfield "Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk email: rjh at the above domain, - www. Jun 20 '07 #8

 P: n/a 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 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. Not in K&R1 since at that time neither undefined not unspecified was defined. -- Flash Gordon Jun 20 '07 #10

 P: n/a Richard Heathfield wrote, On 20/06/07 12:14: Rasjid said: >2) order of evaluation of operands of operators undefined except wherenoted. 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. 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. -- Flash Gordon Jun 20 '07 #11

 P: n/a Flash Gordon said: Richard Heathfield wrote, On 20/06/07 12:14: >Rasjid said: >>2) order of evaluation of operands of operators undefined exceptwhere noted. In fact, the order of evaluation is unspecified rather thanundefined. That means that there /is/ an order of evaluation, butthat order is entirely up to the implementation. 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. -- Richard Heathfield "Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk email: rjh at the above domain, - www. Jun 20 '07 #12

 P: n/a "Richard Heathfield" 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. 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? Jun 20 '07 #13

 P: n/a Rasjid wrote: > .... 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: --

 P: n/a On Jun 21, 10:27 am, CBFalconer

 P: n/a On Jun 20, 7:14 pm, Richard Heathfield

 P: n/a On Wed, 20 Jun 2007 22:53:16 -0700, Rasjid wrote: On Jun 20, 7:14 pm, Richard Heathfield "Except as indicated by the syntax or otherwise specified later(for the function-call operator () , && , || , ?: , and commaoperators), the order of evaluation of subexpressions and the order inwhich side effects take place are both unspecified." This is from msdn2.microsoft, under C Reference Manual:-"Precedence and Order of EvaluationThe precedence and associativity of C operators affect the groupingand evaluation of operands in expressions. An operator's precedence ismeaningful only if other operators with higher or lower precedence arepresent. Expressions with higher-precedence operators are evaluatedfirst. 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 theparagraph necessary? I have to acknowledge I try to be fast. Ifsomeone learns comprehensively and covers and understands everytopics, then there is no problem after. But what about someone whojust wants to check only on order of evaluation when attemptingv = u & -(u = 1);Is it certain that unary - will first be evaluated ? Yes, highestprecedence ! 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 firstassuming all relevant operands have been evaluated as they may beevaluated 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 >Nevertheless, the expression sucks...this one sucks, .... 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 andfor 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 beenthis :-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 Jun 21 '07 #17

 P: n/a "Rasjid" "Except as indicated by the syntax or otherwise specified later(for the function-call operator () , && , || , ?: , and commaoperators), the order of evaluation of subexpressions and the order inwhich 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." The C programming language standard does not require that every implementation works the same as Microsoft's. Jun 21 '07 #18

 P: n/a Richard Heathfield wrote: Rasjid said: >On Jun 20, 7:14 pm, Richard Heathfield >Rasjid said: Ok I accept the Chris Dollin Rule of Thumb - Zero connection 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.) >Life is too easy, I'll suggest changes to C spec... precedence ofoperators determines evaluation of OPERATORS butoperands...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." (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. -- Chris "all thumbs" Dollin Hewlett-Packard Limited Cain Road, Bracknell, registered no: registered office: Berks RG12 1HN 690597 England Jun 21 '07 #19

 P: n/a On 2007-06-21, Barry Schwarz wrote: >>Maybe this is better:-"Expressions with higher-precedence operators are evaluated firstassuming all relevant operands have been evaluated as they may beevaluated 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. 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. Jun 21 '07 #20

 P: n/a Rasjid

 P: n/a CBFalconer said: Rasjid wrote: >> ... snip ... >>The 4 replies basically is in agreement and my main comments isin 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, theneveryone 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). 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. -- Richard Heathfield "Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk email: rjh at the above domain, - www. Jun 21 '07 #22

 P: n/a On Jun 20, 2:23 pm, Richard Heathfield >From the reference manual I have :- 1) "The order of evaluation of subexpressions is determined by the precedence and grouping of operators." It's from BjarneStroustrupC++ ..., 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.) 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 Jun 21 '07 #23

 P: n/a On 21 Jun 2007 10:10:40 GMT, Charles Bailey On 2007-06-21, Barry Schwarz On Wed, 20 Jun 2007 22:53:16 -0700, Rasjid wrote: >>>Maybe this is better:-"Expressions with higher-precedence operators are evaluated firstassuming all relevant operands have been evaluated as they may beevaluated in any order." Still not true. Consider a = b * c + d + e;Multiplication is the highest precedence but it is still legal for d+eto be evaluated prior to a*b. If d+e is a common expression, it mayhave 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-expressiond+e is an additive expression, not a multiplicative-expression socan'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 Jun 21 '07 #24

 P: n/a Rasjid wrote: On Jun 21, 10:27 am, CBFalconer Please do not top-post. Your answer belongs after (or intermixedwith) the quoted material to which you reply, after snipping allirrelevant material. See the following links: Thanks, I test if it works. Why no preview for reply? I have no idea. Try a real newsreader and server rather than the poor google interface. -- cbfalconer at maineline dot net -- Posted via a free Usenet account from http://www.teranews.com Jun 21 '07 #25

 P: n/a Rasjid wrote: > .... 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. -- cbfalconer at maineline dot net -- Posted via a free Usenet account from http://www.teranews.com Jun 21 '07 #26

 P: n/a On 2007-06-21, 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-expressiond+e is an additive expression, not a multiplicative-expression socan'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. 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. Jun 21 '07 #27

 P: n/a On Jun 21, 6:24 pm, r...@hoekstra-uitgeverij.nl (Richard Bos) wrote: 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 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 Jun 21 '07 #28

 P: n/a On Jun 21, 9:48 pm, bjarne

 P: n/a "Rasjid"

 P: n/a 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. -- Richard Heathfield "Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk email: rjh at the above domain, - www. Jun 21 '07 #31

 P: n/a Richard Heathfield wrote: 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. 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? Jun 21 '07 #32

 P: n/a On Jun 22, 4:01 am, "Army1987"

 P: n/a Harald van D?k said: Richard Heathfield wrote: >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 untilit isn't. 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. -- Richard Heathfield "Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk email: rjh at the above domain, - www. Jun 21 '07 #34

 P: n/a "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() afterboth a and b, of course. But any of the ordersx, y, a(), b(), f() orx, y, b(), a(), f() orx, a(), y, b(), f() ory, x, a(), b(), f() ory, x, b(), a(), f() ory, 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 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. Jun 21 '07 #35

 P: n/a Richard Heathfield wrote: Rasjid said: >Order of evaluation is a critical matter in the execution of codes 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.] -- Imperious Not Imperative Hedgehog A rock is not a fact. A rock is a rock. Jun 21 '07 #36

 P: n/a Chris Dollin said: Richard Heathfield wrote: >Rasjid said: >>Order of evaluation is a critical matter in the execution of codes No, it isn't. 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. -- Richard Heathfield "Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk email: rjh at the above domain, - www. Jun 21 '07 #37

 P: n/a On Thu, 21 Jun 2007 10:35:21 -0700, Rasjid wrote: >On Jun 21, 6:24 pm, r...@hoekstra-uitgeverij.nl (Richard Bos) wrote: 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 assuch, 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 nosurprise there; they always insist that their way is the only way, andindustry standards exist so they can break them. I think I learn something , that little knowledge hurts. There is Cand 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 thingsignored! In that particular case it is true. The point is in general it need not be. Remove del for email Jun 22 '07 #38

 P: n/a On Thu, 21 Jun 2007 11:55:24 -0700, Rasjid wrote: >On Jun 21, 9:48 pm, bjarne 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 connectionbetween precedence of operators and order of evaluation ofsubexpressions. I asked for any instance where there is a need toinvoke operator precedence/order rule to resolve things and no oneseem 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 evaluationserves no purpose at all and only causes confusion to unsuspectingusers (potentially many). If the said connection is actually needed inthe C standard, it may be for very rare instances which may be bettersettled in other manner that do not cause confusion. Remove del for email Jun 22 '07 #39

 P: n/a Barry Schwarz said: 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++;) ; You could profitably lose a semicolon from inside that while loop header. -- Richard Heathfield "Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk email: rjh at the above domain, - www. Jun 22 '07 #41

 P: n/a Harald van D?k wrote: > .... snip ... > Okay, how would you then rewrite if (p != NULL && p->data == 1234) { /* A */ } else { /* B */ } Why should you even consider rewriting it? (Your first version was WRONG, BAD, FOOBAR, etc.) -- cbfalconer at maineline dot net -- Posted via a free Usenet account from http://www.teranews.com Jun 22 '07 #42

 P: n/a On Jun 22, 8:13 am, Barry Schwarz

 P: n/a Rasjid wrote: > .... snip ... > My carelessness. Fortunately I post here only after learning rules on precedence of operators is a must. My request was for a single example where order of evaluation is determined by precedence of operators. You have been told (and ignored) that no such thing exists. -- cbfalconer at maineline dot net -- Posted via a free Usenet account from http://www.teranews.com Jun 22 '07 #44

 P: n/a CBFalconer wrote: Harald van D?k wrote: >> ... snip ... >>Okay, how would you then rewriteif (p != NULL && p->data == 1234) { /* A */} else { /* B */} Why should you even consider rewriting it? (Your first version was WRONG, BAD, FOOBAR, etc.) You shouldn't. The message that I replied to (which you snipped) claimed that you should. That was clearly not what Richard meant (as he has also replied) and my message was an attempt to point that out -- a not too good attempt, it seems. Jun 22 '07 #45

 P: n/a "CBFalconer" > ... snip ... >>My carelessness. Fortunately I post here only after learning ruleson precedence of operators is a must. My request was for a singleexample where order of evaluation is determined by precedence ofoperators. You have been told (and ignored) that no such thing exists. *a(c = g(y)) += b[f(x)]; Of course g() must be called before c is assigned... Jun 22 '07 #46

 P: n/a In article , Army1987 *a(c = g(y)) += b[f(x)];Of course g() must be called before c is assigned... What if the compiler can statically determine that g() always returns zero? There is a sequence point before procedure call, but I find the wording on sequence points so confusing that I can't be sure what it implies in this case - "no side effects of subsequent evaluations shall have taken place", but what determines that the assignment to c is a *subsequent* evaluation? -- Richard -- "Consideration shall be given to the need for as many as 32 characters in some alphabets" - X3.4, 1963. Jun 22 '07 #47

 P: n/a Richard Tobin wrote: In article , Army1987 wrote: >>*a(c = g(y)) += b[f(x)];Of course g() must be called before c is assigned... What if the compiler can statically determine that g() always returns zero? And what if the compiler can statically determine that g() always returns c? Does that mean it's allowed to set c to whatever it wants, and then call g? In both your and my case, I'm confident the intended answer is just what Army1987 claimed (though of course, if the visible behaviour remains the same, the as-if rule applies), but I cannot find a definitive answer. Jun 23 '07 #48

 P: n/a On Wed, 20 Jun 2007 +0200, "Army1987" "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 inC/C++ and the related issue of precedence of operators, use ofparentheses. >>>From the reference manual I have :- 1) "The order of evaluation of subexpressions is determined by theprecedence and grouping of operators."2) order of evaluation of operands of operators undefined except wherenoted.I was just told at another forum thatv = u - ((u & -(u = 1)) << 1);has undefined behavior and the reason given wasthe 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 aboutx = 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 + ccan work ast1 = a; t2 = b; t3 = c; t4 = t1 * t2; t5 = t4 * t3; x = t5; ev=evalute what about t1=ev(a); t2=ev(b); t3=t1*t2; t4=ev(c); t5=t3+t4; x=t5; what about x= ++a() * --b() + ++c(); t1=++ev(a()); t2=--ev(b()); t3=t1*t2; t4=++ev(c()); t5=t3+t4; x=t5; and if function is more complex? x=m>3?a:b; t1=ev(m): if(t1>3) Return(ev(a)) else Return(ev(b)) >or any reshuffling of these. The only requirement is (of course)that t4 gets assigned after both t1 and t2 do, t5 gets assignedafter t4 and t3 do, and x is assigned after t5. Any otherreordering is allowed. Jun 24 '07 #49

 P: n/a On Sun, 24 Jun 2007 07:40:22 +0200, in comp.lang.c , "¬a\\/b" wrote: >ev=evalutewhat aboutt1=ev(a); t2=ev(b); t3=t1*t2; t4=ev(c); t5=t3+t4; x=t5; the semicolons introduce sequence points. >what about x= ++a() * --b() + ++c(); Error - you can't increment a function. >t1=++ev(a()); t2=--ev(b()); t3=t1*t2; t4=++ev(c()); t5=t3+t4; x=t5; Ditto. -- Mark McIntyre "Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." --Brian Kernighan Jun 24 '07 #50

54 Replies

### This discussion thread is closed

Replies have been disabled for this discussion.

### Similar topics

Browse more C / C++ Questions on Bytes