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