digitalmars.D - Chained method argument evaluation order
- Jarrett Billingsley (37/37) Jan 16 2008 Something tells me this was discussed before, but sheesh..
- Sean Kelly (13/56) Jan 16 2008 I think this is actually documented here:
- Jason House (4/5) Jan 16 2008 I'd expect the calls to be done in an implementation-dependent order. I...
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.
Jan 16 2008
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
Jan 16 2008
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.
Jan 16 2008