Thread overview | |||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
June 13, 2013 Expression evaluation order | ||||
---|---|---|---|---|
| ||||
There is a test in the DMD testsuite that verifies that the evaluation order in the following statement a()[] = b()[] + c()[]; is b, c, a. I'm trying to figure out why this regressed with the 2.063 merge in LDC, but (where) is this specified in the first place? David |
June 13, 2013 Re: Expression evaluation order | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Nadlinger | On Friday, June 14, 2013 01:09:18 David Nadlinger wrote:
> There is a test in the DMD testsuite that verifies that the evaluation order in the following statement
>
> a()[] = b()[] + c()[];
>
> is b, c, a.
>
> I'm trying to figure out why this regressed with the 2.063 merge in LDC, but (where) is this specified in the first place?
Walter has expressed a desire in the past to make it so that D requires that the evaluation order of arguments be left-to-right in order to avoid bugs, and while these aren't exactly function arguments, they're basically function arguments to a built-in function called +, so I could definitely see Walter wanting to require that the evaluation order be left-to-right. However, while Walter has expressed an interest in making it a requirement, AFAIK, it has never officially become one and the spec says nothing on the matter.
- Jonathan M Davis
|
June 13, 2013 Re: Expression evaluation order | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | Jonathan M Davis:
> Walter has expressed a desire in the past to make it so that D requires that the evaluation order of arguments be left-to-right
> in order to avoid bugs,
Considering how much important this feature is, I think it should have priority over several other things.
Bye,
bearophile
|
June 14, 2013 Re: Expression evaluation order | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Thursday, 13 June 2013 at 23:25:42 UTC, Jonathan M Davis wrote:
> Walter has expressed a desire in the past to make it so that D requires that
> the evaluation order of arguments be left-to-right in order to avoid bugs, and
> while these aren't exactly function arguments, …
Actually, behind the scenes all three are arguments to *one* function call: the druntime array op implementation.
Anyway, my question was mainly about the assignment operator, which is obviously not expected to behave lexically left-to-right by that test case.
David
|
June 14, 2013 Re: Expression evaluation order | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Nadlinger | On Friday, June 14, 2013 02:02:23 David Nadlinger wrote:
> On Thursday, 13 June 2013 at 23:25:42 UTC, Jonathan M Davis wrote:
> > Walter has expressed a desire in the past to make it so that D
> > requires that
> > the evaluation order of arguments be left-to-right in order to
> > avoid bugs, and
> > while these aren't exactly function arguments, …
>
> Actually, behind the scenes all three are arguments to *one* function call: the druntime array op implementation.
>
> Anyway, my question was mainly about the assignment operator, which is obviously not expected to behave lexically left-to-right by that test case.
I don't see how the assignment operator could possibly work left-to-right, though I could see how there might be a question with regards to whether what's on the left of the assignment operator would be evaluated before what's on the right when what's on the left is an expression rather than a variable. Personally, I would expect it to fully evaluate the right-hand side of an assignment expression before evaluating anything on the left, and I'd expect the same of any operator which is right-associative, but I'm not aware of anything official on the matter. All the discussions on the matter that I'm aware of have referred specifically to function arguments being left-to-right and said nothing about operators.
- Jonathan M Davis
|
June 14, 2013 Re: Expression evaluation order | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Friday, 14 June 2013 at 00:13:37 UTC, Jonathan M Davis wrote:
> I don't see how the assignment operator could possibly work left-to-right,
> though I could see how there might be a question with regards to whether
> what's on the left of the assignment operator would be evaluated before what's
> on the right when what's on the left is an expression rather than a variable.
SDC compute the address of the reciever, then the value on the right, and finally store it to the address. I don't see any major issue here.
|
June 14, 2013 Re: Expression evaluation order | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Friday, 14 June 2013 at 00:13:37 UTC, Jonathan M Davis wrote: > On Friday, June 14, 2013 02:02:23 David Nadlinger wrote: >> On Thursday, 13 June 2013 at 23:25:42 UTC, Jonathan M Davis wrote: >> > Walter has expressed a desire in the past to make it so that D >> > requires that >> > the evaluation order of arguments be left-to-right in order to >> > avoid bugs, and >> > while these aren't exactly function arguments, … >> >> Actually, behind the scenes all three are arguments to *one* >> function call: the druntime array op implementation. >> >> Anyway, my question was mainly about the assignment operator, >> which is obviously not expected to behave lexically left-to-right >> by that test case. > > I don't see how the assignment operator could possibly work left-to-right What do you mean? assignment requires two arguments: the *reference* of lhs, and value/reference or rhs. Regardless of if lhs is a value or expression, the compiler still needs to know *where* to assign to. I don't see any reasons why the compiler couldn't choose lhs first instead. *as* a matter of fact, that's how gcc does it for C++: //---- int main() { int i = 0; ++i = ++i; assert(i == 2); //passes } //---- Left to right First, evaluate lhs: i has the value 1. then evaluate rhs, which will now have the value 2. assign 2 to i. * i == 2 * right to left: First, evalutate rhs: i has the value 1, an rhs 1. Evaluate lhs: i is now 2. But then assign rhs (1) to lhs. * i == 1 * So yeah, left to right evaluation is completely coherent, and a valid scheme. Heck, you'll notice this *also* passes with DMD, so dmd *also* evaluates opEqual left to right. So I guess this "surprising behavior" is the evaluation order we want to enforce? --------- I remember the discussion: http://forum.dlang.org/thread/bniaxycuguviwfdtojzf@forum.dlang.org For the record, I don't remember there being a consensus... at all... There were 3.5 positions: 1) left to right evaluation 2) right to left evaluation 3) specifically unspecified 3.5) error when compiler sees ambiguity I'm personally in favor of 3, with some 3.5 as a warning. Evaluation order, even when defined, remains obscure once associative operations come into play, and still bite you in the ass anyways, so I don't see anything good out of forcing it one way or the other anyways. |
June 14, 2013 Re: Expression evaluation order | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Nadlinger | On 14 June 2013 00:09, David Nadlinger <code@klickverbot.at> wrote:
> There is a test in the DMD testsuite that verifies that the evaluation order in the following statement
>
> a()[] = b()[] + c()[];
>
> is b, c, a.
>
> I'm trying to figure out why this regressed with the 2.063 merge in LDC, but (where) is this specified in the first place?
>
> David
Interesting, that certainly doesn't flag up as a regression in the 2.063 merge in GDC... :o)
However yes, the behaviour relies on the order the sucky X86 ABI pushes arguments onto the stack (which for this array op is from right to left). Whereas on *all* other architectures it will execute the parameters in left to right order, which would be a, c, b in this case.
--
Iain Buclaw
*(p < e ? p++ : p) = (c & 0x0f) + '0';
|
June 14, 2013 Re: Expression evaluation order | ||||
---|---|---|---|---|
| ||||
Posted in reply to Iain Buclaw | Iain Buclaw:
> However yes, the behaviour relies on the order the sucky X86 ABI
> pushes arguments onto the stack (which for this array op is from right
> to left). Whereas on *all* other architectures it will execute the
> parameters in left to right order, which would be a, c, b in this case.
D needs the same standard order of evaluations for all expressions on all compilers, regardless of the CPUs. The only other acceptable alternative is to statically forbid code that risks having variable results.
(And I think the right order for that is b, c, a).
Bye,
bearophile
|
June 14, 2013 Re: Expression evaluation order | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Friday, 14 June 2013 at 11:04:04 UTC, bearophile wrote:
> (And I think the right order for that is b, c, a).
Could you derive a set of rules from/compatible with that thought? ;)
David
|
Copyright © 1999-2021 by the D Language Foundation