| Thread overview | |||||
|---|---|---|---|---|---|
|
January 16, 2008 Chained method argument evaluation order | ||||
|---|---|---|---|---|
| ||||
Something tells me this was discussed before, but sheesh..
int a() { Stdout.formatln("A"); return 1; }
int b() { Stdout.formatln("B"); return 2; }
struct S
{
S* chain(int x)
{
Stdout.formatln("{}", x);
return this;
}
}
void main()
{
S s;
s.chain(a()).chain(b());
}
This prints the following compiled with DMDWin:
B
A
1
2
Notice that the chained methods are called in the right order, but that their arguments -- even though they're in different function calls!! -- are evaluated in _reverse_ order, and _before_ any of the chained methods are called.
I really wouldn't have expected this. I _would_ have expected
A
1
B
2
But the compiler must be being clever here, for some reason.
Should this kind of thing be documented, specified, implementation-dependent etc.? Because I would have expected the chained call above to basically be evaluated as:
auto t = s.chain(a());
t.chain(b());
which gives the expected output above.
| ||||
January 16, 2008 Re: Chained method argument evaluation order | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Jarrett Billingsley wrote: > Something tells me this was discussed before, but sheesh.. > > int a() { Stdout.formatln("A"); return 1; } > int b() { Stdout.formatln("B"); return 2; } > > struct S > { > S* chain(int x) > { > Stdout.formatln("{}", x); > return this; > } > } > > void main() > { > S s; > s.chain(a()).chain(b()); > } > > This prints the following compiled with DMDWin: > > B > A > 1 > 2 > > Notice that the chained methods are called in the right order, but that their arguments -- even though they're in different function calls!! -- are evaluated in _reverse_ order, and _before_ any of the chained methods are called. > > I really wouldn't have expected this. I _would_ have expected > > A > 1 > B > 2 > > But the compiler must be being clever here, for some reason. > > Should this kind of thing be documented, specified, implementation-dependent etc.? I think this is actually documented here: http://www.digitalmars.com/d/1.0/expression.html In the "Expression Order" section. Basically, I think that: a.op(b).op(c) is equivalent to: (a + b) + c In terms of evaluation. ie. I think you can be sure that the a.op(b) function will be called first and that b will be evaluated before this call takes place, but that's it. The compiler is free to evaluate b and c both before this call, and to do so in any order. However, I think Walter is planning on changing this for 2.0. Sean | |||
January 17, 2008 Re: Chained method argument evaluation order | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Jarrett Billingsley wrote:
> I really wouldn't have expected this.
I'd expect the calls to be done in an implementation-dependent order. It reminds me of stuff like "a = b++ + b++;" which is a classic example of undefined behavior.
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply