Thread overview | ||||||
---|---|---|---|---|---|---|
|
August 09, 2005 Chaining Bug | ||||
---|---|---|---|---|
| ||||
The following code outputs "0" instead of "5" on DMD 0.129 on Linux. This is preventing chaining from working properly in my new containers library in some cases. ------------------ import std.stdio; void main() { A a = new A; int val; a.foo(val).bar(val); } class A { A foo(out int val) { val = 5; return this; } A bar(int val) { writefln("%d", val); return this; } } ---------------------- |
August 09, 2005 Re: Chaining Bug | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Demme | > The following code outputs "0" instead of "5" on DMD 0.129 on Linux.
> This is preventing chaining from working properly in my new containers
> library in some cases.
>
> ------------------
> import std.stdio;
>
> void main() {
> A a = new A;
> int val;
> a.foo(val).bar(val);
> }
>
> class A {
> A foo(out int val) {
> val = 5;
> return this;
> }
> A bar(int val) {
> writefln("%d", val);
> return this;
> }
> }
> ----------------------
This is very interesting. The following assembler code is generated for the chained call:
#########
; Initialize out parameter val with 0.
xor ECX,ECX
mov -4[EBP],ECX
; Push the value of val.
push ECX
; Push the address of val.
lea EDX,-4[EBP]
push EDX
; Call foo()
mov EBX,[EAX]
call dword ptr 018h[EBX]
; Call bar()
mov ESI,[EAX]
call dword ptr 01Ch[ESI]
###########
As you can see, the values for chained calls are already accumulated on the stack. Not sure if this is even desired behaviour... I remember reading something like "It is illegal to rely on the evaluation behaviour of function parameters" in the specs, which would apply to things like this:
###
callSomeFunc(i, ++i);
###
Perhaps this rule is extended to all parameters in a call chain?
Anyways, you could fix your library by passing the value as inout into bar.
Ciao
uwe
|
August 09, 2005 Re: Chaining Bug | ||||
---|---|---|---|---|
| ||||
Posted in reply to Uwe Salomon | Uwe Salomon wrote: <snip> > As you can see, the values for chained calls are already accumulated on the stack. Not sure if this is even desired behaviour... I remember reading something like "It is illegal to rely on the evaluation behaviour of function parameters" in the specs, which would apply to things like this: > > ### > callSomeFunc(i, ++i); > ### > > Perhaps this rule is extended to all parameters in a call chain? It's just one case of the rule. The dependency structure is like this a &val | | | a.foo(val) val | | a.foo(val).bar(val) and so the compiler has the right to evaluate val before it evaluates a.foo(val). The only way to force evaulation order is to use separate statements or, where possible, a comma operator. > Anyways, you could fix your library by passing the value as inout into bar. It took me a moment to see how it would help.... Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on on the 'group where everyone may benefit. |
August 09, 2005 Re: Chaining Bug | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stewart Gordon | Well, I guess I got burned there. I expected if it was something like this, that it would only happen if I compiled with -O, so I tried it both ways.
I guess I'll just change it to inout.
On Tue, 2005-08-09 at 17:50 +0100, Stewart Gordon wrote:
> Uwe Salomon wrote:
> <snip>
> > As you can see, the values for chained calls are already accumulated on the stack. Not sure if this is even desired behaviour... I remember reading something like "It is illegal to rely on the evaluation behaviour of function parameters" in the specs, which would apply to things like this:
> >
> > ###
> > callSomeFunc(i, ++i);
> > ###
> >
> > Perhaps this rule is extended to all parameters in a call chain?
>
> It's just one case of the rule. The dependency structure is like this
>
> a &val
> | | |
> a.foo(val) val
> | |
> a.foo(val).bar(val)
>
> and so the compiler has the right to evaluate val before it evaluates a.foo(val). The only way to force evaulation order is to use separate statements or, where possible, a comma operator.
>
> > Anyways, you could fix your library by passing the value as inout into bar.
>
> It took me a moment to see how it would help....
>
> Stewart.
>
|
Copyright © 1999-2021 by the D Language Foundation