Jump to page: 1 2 3
Thread overview
Expression evaluation order
Jun 13, 2013
David Nadlinger
Jun 13, 2013
Jonathan M Davis
Jun 13, 2013
bearophile
Jun 14, 2013
David Nadlinger
Jun 14, 2013
Jonathan M Davis
Jun 14, 2013
deadalnix
Jun 14, 2013
monarch_dodra
Jun 14, 2013
bearophile
Jun 15, 2013
Walter Bright
Jun 15, 2013
monarch_dodra
Jun 14, 2013
Timon Gehr
Jun 15, 2013
Jonathan M Davis
Jun 15, 2013
Timon Gehr
Jun 15, 2013
Timon Gehr
Jun 14, 2013
w0rp
Jun 14, 2013
Iain Buclaw
Jun 14, 2013
bearophile
Jun 14, 2013
David Nadlinger
Jun 14, 2013
Iain Buclaw
Jun 14, 2013
Timon Gehr
Jun 15, 2013
David Nadlinger
Jun 15, 2013
Iain Buclaw
Jun 14, 2013
Johannes Pfau
June 13, 2013
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
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
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
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
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
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
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
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
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
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
« First   ‹ Prev
1 2 3