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









Sean Kelly <sean f4.ca> 