digitalmars.D - Evaluation Order
- Sean Kelly (10/13) May 29 2004
- Andy Friesen (8/23) May 29 2004 The result is well defined, but the order in which the terms are
- Sean Kelly (5/13) May 29 2004 Ah, that's what I figured but the attached examples had me wondering.
- Bent Rasmussen (25/25) May 29 2004 I'd guess this has something to do with side-effects. If you have a bool...
- Sean Kelly (13/35) May 29 2004 That was my guess too, but "expressions" was sufficiently vage that I
- Walter (9/20) May 29 2004 There are two different things going on here - one is evaluation order, ...
- Arcane Jill (19/23) May 29 2004 Is precedence order defined the same way in D that it is in C?
- Walter (12/34) May 29 2004 and
- Juan C (5/9) May 30 2004 D would appeal more to _this_ C programmer if _all_ the flaws of C/C++ w...
- Walter (5/7) May 30 2004 were
- Kevin Bealer (12/35) May 30 2004 I remember that "*" is before "+", comparisons (<, ==) are before "&&" a...
-
Vathix
(11/16)
May 30 2004
"Kevin Bealer"
wrote in message - Juan c (1/5) May 30 2004 Don't they return true or false?
- Kevin Bealer (19/36) May 31 2004 The purpose of this, conceptually, is that there are a lot of times in C...
- J Anderson (7/62) May 30 2004 You mean?
This bit from the spec has me concerned:Unless otherwise specified, the implementation is free to evaluate the components of an expression in any order. It is an error to depend on order of evaluation when it is not specified.C++ has well-defined evaluation rules, and this almost seems necessary for complex mathematical expressions. But aside from logical operators and the comma operator I can't find any information on eevaluation order in the D spec. For example, this expression: int x = 5 * 4 / 3; has a well-defined result in C/C++, but does it in D? Or should perenthesis always be used? Sean
May 29 2004
Sean Kelly wrote:This bit from the spec has me concerned: >Unless otherwise specified, the implementation is free to evaluate the >components of an expression in any order. It is an error to depend on >order of evaluation when it is not specified. C++ has well-defined evaluation rules, and this almost seems necessary for complex mathematical expressions. But aside from logical operators and the comma operator I can't find any information on eevaluation order in the D spec. For example, this expression: int x = 5 * 4 / 3; has a well-defined result in C/C++, but does it in D? Or should perenthesis always be used?The result is well defined, but the order in which the terms are evaluated is not. That part of the spec pertains to something like this: int x = (5 * 4) + (3 / 2); D reserves the right to compute either the multiply or divide first. Obviously, since the addition needs the result of both, it is going to be last. -- andy
May 29 2004
Andy Friesen wrote:The result is well defined, but the order in which the terms are evaluated is not. That part of the spec pertains to something like this: int x = (5 * 4) + (3 / 2); D reserves the right to compute either the multiply or divide first. Obviously, since the addition needs the result of both, it is going to be last.Ah, that's what I figured but the attached examples had me wondering. So D follows standard operator precedence rules and evaluation order for all scenarios I care about :) Sean
May 29 2004
I'd guess this has something to do with side-effects. If you have a boolean expression like a || b and both sides exhibit side-effects, you can't rely on any order of evaluation to determine which side-effect takes place first. Perhaps you can't even be sure that both sides of the above expression will be evaluated if any of the sides evaluate to true. I don't know though. The specification has an example where the order of evaluation affects the value of the expression c = a + (a = b) So here the order of evaluation affects c which it would seem easy for the compiler to detect. Of course its easy to construct difficult cases. In such a simple example it would seem no problem to detect order of evaluation dependency but of course its easy to construct an example where its much harder to detect that evaluation order affects the result. It seems like a good principle for stuff like assertions that use boolean expressions. Further examination of the spec says "The OrOr expression evaluates its left operand. If the left operand, converted to type bool, evaluates to true, then the right operand is not evaluated." It makes sense and of course if you expected the right operand to evaluate because it exhibits some side-effect then you'll be disappointed and that's how it should be it seems to me. I think Eiffel has allways evaluates the full boolean expression except if you use "and then" or "or else".
May 29 2004
Bent Rasmussen wrote:I'd guess this has something to do with side-effects. If you have a boolean expression like a || b and both sides exhibit side-effects, you can't rely on any order of evaluation to determine which side-effect takes place first. Perhaps you can't even be sure that both sides of the above expression will be evaluated if any of the sides evaluate to true. I don't know though.That was my guess too, but "expressions" was sufficiently vage that I wanted to ask.The specification has an example where the order of evaluation affects the value of the expression c = a + (a = b)This is the example that threw me. I had thought that the parenthesis would force the assignment to occur before the addition, even though assignments are typically fairly low on the precedence tree.Further examination of the spec says "The OrOr expression evaluates its left operand. If the left operand, converted to type bool, evaluates to true, then the right operand is not evaluated."This is required for short-circuit evaluation. The AndAnd bit has a similar clause. But they're just about the only expressions that mention evaluation, so I was left wondering. (for the record, the comma operator and the logical if operators also mention evaluation order).It makes sense and of course if you expected the right operand to evaluate because it exhibits some side-effect then you'll be disappointed and that's how it should be it seems to me. I think Eiffel has allways evaluates the full boolean expression except if you use "and then" or "or else".Yup. Some of the .NET languages are like this also. Frankly, it drives me crazy :) I guess I've just become accustomed to the C/C++ method. Sean
May 29 2004
"Sean Kelly" <sean f4.ca> wrote in message news:c9ase5$a2c$1 digitaldaemon.com...This bit from the spec has me concerned: >Unless otherwise specified, the implementation is free to evaluate the >components of an expression in any order. It is an error to depend on >order of evaluation when it is not specified. C++ has well-defined evaluation rules, and this almost seems necessary for complex mathematical expressions. But aside from logical operators and the comma operator I can't find any information on eevaluation order in the D spec. For example, this expression: int x = 5 * 4 / 3; has a well-defined result in C/C++, but does it in D? Or should perenthesis always be used?There are two different things going on here - one is evaluation order, and the other is the operator precedence, associativity and commutativity rules. The latter are well defined, in D as well as C++, and in your example evaluates as (5*4)/3. The former are not, in D and C++. For example: (a + b) * (c + d) which is evaluated first, (a + b) or (c + d)? The specification leaves this up to the compiler in both languages.
May 29 2004
In article <c9blde$1bs0$3 digitaldaemon.com>, Walter says...There are two different things going on here - one is evaluation order, and the other is the operator precedence, associativity and commutativity rules. The latter are well defined, in D as well as C++,Is precedence order defined the same way in D that it is in C? I ask because I think C got it wrong, and I'd hate to think we were copying the flaws as well as the good bits. I always thought it a mistake that the precedence of &, | and ^ was defined such that:if (a & 1 == 1)gives (1 == 1) precedence over (a & 1). It's not intuitive in C. C++ copied it, and it's not intuitive in C++. I think even Java copied it, and it's not intuitive there either. Believe it or not, I think BASIC got this right! I would prefer precedence order to be: << >> & ^ | * / % + - < > <= >= etc == != && || (but I guess it would break too much to change that now). Arcane Jill
May 29 2004
"Arcane Jill" <Arcane_member pathlink.com> wrote in message news:c9bssf$1mld$1 digitaldaemon.com...In article <c9blde$1bs0$3 digitaldaemon.com>, Walter says...andThere are two different things going on here - one is evaluation order,rules.the other is the operator precedence, associativity and commutativityYes.The latter are well defined, in D as well as C++,Is precedence order defined the same way in D that it is in C?I ask because I think C got it wrong, and I'd hate to think we werecopying theflaws as well as the good bits. I always thought it a mistake that the precedence of &, | and ^ wasdefined suchthat:copied it,if (a & 1 == 1)gives (1 == 1) precedence over (a & 1). It's not intuitive in C. C++and it's not intuitive in C++. I think even Java copied it, and it's not intuitive there either. Believe it or not, I think BASIC got this right! I would prefer precedence order to be: << >> & ^ | * / % + - < > <= >= etc == != && || (but I guess it would break too much to change that now).Since D is designed to appeal to C/C++ programmers, changing the precedence order that, for good or ill, we're all used to would introduce subtle bugs. I'd prefer to change only things that would yield obvious errors if done using the C/C++ semantics.
May 29 2004
Since D is designed to appeal to C/C++ programmers, changing the precedence order that, for good or ill, we're all used to would introduce subtle bugs. I'd prefer to change only things that would yield obvious errors if done using the C/C++ semantics.D would appeal more to _this_ C programmer if _all_ the flaws of C/C++ were fixed. On the other hand, I believe that the last time this particular concern was raised, Walter was able to convince me that this was the _correct_ order. However, I seem to recall that my agreement required that boolean not be implicitly cast to or from other types.
May 30 2004
"Juan C" <Juan_member pathlink.com> wrote in message news:c9ctl4$sg$1 digitaldaemon.com...D would appeal more to _this_ C programmer if _all_ the flaws of C/C++werefixed.The trouble with that is there is little agreement on what _all_ the flaws are!
May 30 2004
In article <c9bssf$1mld$1 digitaldaemon.com>, Arcane Jill says...In article <c9blde$1bs0$3 digitaldaemon.com>, Walter says...I remember that "*" is before "+", comparisons (<, ==) are before "&&" and "||", and maybe one or two others. For almost everything else I use the parens, for readability and safety. I don't expect the compiler to get it wrong, but I know that I will, and I hate debugging this stuff: I'd rather be hunting orc than squirrel if you get my meaning. Incidentally, what are "&&" and "||" supposed to return? I think at one point I read that || returns the first argument that is true, or the second argument, but I tried it and it didn't work in whatever language I was using. It would be useful if you could say: (return x || y || 100), but I don't know if that makes sense in the bigger picture. KevinThere are two different things going on here - one is evaluation order, and the other is the operator precedence, associativity and commutativity rules. The latter are well defined, in D as well as C++,Is precedence order defined the same way in D that it is in C? I ask because I think C got it wrong, and I'd hate to think we were copying the flaws as well as the good bits. I always thought it a mistake that the precedence of &, | and ^ was defined such that:if (a & 1 == 1)gives (1 == 1) precedence over (a & 1). It's not intuitive in C. C++ copied it, and it's not intuitive in C++. I think even Java copied it, and it's not intuitive there either. Believe it or not, I think BASIC got this right! I would prefer precedence order to be: << >> & ^ | * / % + - < > <= >= etc == != && || (but I guess it would break too much to change that now). Arcane Jill
May 30 2004
"Kevin Bealer" <Kevin_member pathlink.com> wrote in message news:c9c6uu$24ul$1 digitaldaemon.com... ...Incidentally, what are "&&" and "||" supposed to return? I think at onepoint Iread that || returns the first argument that is true, or the secondargument,but I tried it and it didn't work in whatever language I was using. Itwould beuseful if you could say: (return x || y || 100), but I don't know if thatmakessense in the bigger picture.JavaScript does that with ||, like alert("foo" || "bar"); displays "foo". I've never used it in real code, but it is interesting. C style languages just return 0 for false and 1 for true; which is depended on in some cases. Changing it would cause those "subtle bugs" I would think.
May 30 2004
JavaScript does that with ||, like alert("foo" || "bar"); displays "foo". I've never used it in real code, but it is interesting. C style languages just return 0 for false and 1 for true; which is depended on in some cases. Changing it would cause those "subtle bugs" I would think.Don't they return true or false?
May 30 2004
In article <c9cpc5$2si0$1 digitaldaemon.com>, Vathix says..."Kevin Bealer" <Kevin_member pathlink.com> wrote in message news:c9c6uu$24ul$1 digitaldaemon.com... ...The purpose of this, conceptually, is that there are a lot of times in C, at least, where you might like to do something like this: void bar(int x, int y, char * optional_arg) { char * baz = optional_arg || getenv("BAR_BAZ") || "<default>"; .. } Since C uses pointers for everything, and a non-null pointer is true, this allows you to pick the first "value source" that is non-null. If you take advantage of this, you can program very readable code: a sequence of "||", read as "or else try", is very understandable compared to an if-then-else pile. It shouldn't hurt semantics either: work out the above and you can see that if "baz" is tested as a boolean, taking the first "nonzero" value, or the last value in the chain (the second, in the 2-argument case) will work. Maybe none of this is true in D. I don't expect this would work in the presence of objects, since boolean bitmath and operator overloading probably clobber it. It's not a feature request, just wondered what I was remembering it from. KevinIncidentally, what are "&&" and "||" supposed to return? I think at onepoint Iread that || returns the first argument that is true, or the secondargument,but I tried it and it didn't work in whatever language I was using. Itwould beuseful if you could say: (return x || y || 100), but I don't know if thatmakessense in the bigger picture.JavaScript does that with ||, like alert("foo" || "bar"); displays "foo". I've never used it in real code, but it is interesting. C style languages just return 0 for false and 1 for true; which is depended on in some cases. Changing it would cause those "subtle bugs" I would think.
May 31 2004
Kevin Bealer wrote:In article <c9bssf$1mld$1 digitaldaemon.com>, Arcane Jill says...You mean? return (x || y || 100); Which logically will always return true because anything other then zero = true; -- -Anderson: http://badmama.com.au/~anderson/In article <c9blde$1bs0$3 digitaldaemon.com>, Walter says...I remember that "*" is before "+", comparisons (<, ==) are before "&&" and "||", and maybe one or two others. For almost everything else I use the parens, for readability and safety. I don't expect the compiler to get it wrong, but I know that I will, and I hate debugging this stuff: I'd rather be hunting orc than squirrel if you get my meaning. Incidentally, what are "&&" and "||" supposed to return? I think at one point I read that || returns the first argument that is true, or the second argument, but I tried it and it didn't work in whatever language I was using. It would be useful if you could say: (return x || y || 100), but I don't know if that makes sense in the bigger picture. KevinThere are two different things going on here - one is evaluation order, and the other is the operator precedence, associativity and commutativity rules. The latter are well defined, in D as well as C++,Is precedence order defined the same way in D that it is in C? I ask because I think C got it wrong, and I'd hate to think we were copying the flaws as well as the good bits. I always thought it a mistake that the precedence of &, | and ^ was defined such that:if (a & 1 == 1)gives (1 == 1) precedence over (a & 1). It's not intuitive in C. C++ copied it, and it's not intuitive in C++. I think even Java copied it, and it's not intuitive there either. Believe it or not, I think BASIC got this right! I would prefer precedence order to be: << >> & ^ | * / % + - < > <= >= etc == != && || (but I guess it would break too much to change that now). Arcane Jill
May 30 2004