Chained method argument evaluation order

Sean Kelly sean at f4.ca
Wed Jan 16 07:33:31 PST 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



More information about the Digitalmars-d mailing list