www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - * bogus codegen with static opAssign() usage *

reply kris <foo bar.com> writes:
Using static opAssign() apparently has some codegen issues. The 
following snippets are two variations of the same code; the first one is 
correct while the second is broken. Only flag enabled is -g. First, the 
operational version, which invokes this.opAssign() explicitly:

; FileProxy parent = this.opAssign(this.parent());
mov	EAX,-010h[EBP]
call	near ptr _D5tango2io8FilePath8FilePath6parentMFZAa
push	EDX
push	EAX
call	near ptr 
_D5tango2io9FileProxy9FileProxy8opAssignFAaZC5tango2io9FileProxy9FileProxy
mov	-0Ch[EBP],EAX

; char[] name = parent.name;
call	near ptr _D5tango2io8FilePath8FilePath4nameMFZAa
mov	-8[EBP],EAX
mov	-4[EBP],EDX


And now the busted version using opAssign() implicitly:


; FileProxy parent = this.parent();
mov	EAX,-010h[EBP]
call	near ptr _D5tango2io8FilePath8FilePath6parentMFZAa
push	EDX
push	EAX
call	near ptr 
_D5tango2io9FileProxy9FileProxy8opAssignFAaZC5tango2io9FileProxy9FileProxy
 doh! where did the return value go? <<<
; char[] name = parent.name; mov EAX,-0Ch[EBP] call near ptr _D5tango2io8FilePath8FilePath4nameMFZAa mov -8[EBP],EAX mov -4[EBP],EDX It's pretty clear that the broken version is discarding the result of the implicit opAssign() call; the assignment is simply being dropped. I'm copying this here since it'll just get lost amongst the weeds in d.bugs. I don't have a small test case: took hours to track this down as it was, and it's deep in the Tango library.
Feb 18 2007
parent reply Walter Bright <newshound digitalmars.com> writes:
	a = b;

is replaced with:

	a.opAssign(b);

not:

	a = a.opAssign(b);

The return value of opAssign comes in to play with:

	c = a = b;

which is rewritten as:

	c = a.opAssign(b);
Feb 18 2007
next sibling parent Gregor Richards <Richards codu.org> writes:
Walter Bright wrote:
     a = b;
 
 is replaced with:
 
     a.opAssign(b);
 
 not:
 
     a = a.opAssign(b);
 
 The return value of opAssign comes in to play with:
 
     c = a = b;
 
 which is rewritten as:
 
     c = a.opAssign(b);
This makes quite a bit of sense, actually. It's consistent. But it begs the question: Is there a way to do what is desired here? That is: SomeClass a = "Instance generated by a string"; - Gregor Richards
Feb 19 2007
prev sibling parent reply kris <foo bar.com> writes:
Walter Bright wrote:
     a = b;
 
 is replaced with:
 
     a.opAssign(b);
 
 not:
 
     a = a.opAssign(b);
 
 The return value of opAssign comes in to play with:
 
     c = a = b;
 
 which is rewritten as:
 
     c = a.opAssign(b);
Doh! Doh! Doh! My bad; I saw this elsewhere and just assumed it would operate correctly. The syntax, however, is very clean. Importantly, it supports the unification or /centralization/ of all those 'new' invocations. I'd go so far as to say such a syntax could represent a bridge between OO and scripting: ---- String s = "mystring"; ---- ---- File f = "/foo/bar.d"; ---- ---- Regex r = "^(.*)$"; ---- There's a fairly wide range of simple applicability for this kinda' thing. Would be great if static opAssign() could support this, or some other operator were enabled? How about it?
Feb 19 2007
next sibling parent kris <foo bar.com> writes:
kris wrote:
 Walter Bright wrote:
 
     a = b;

 is replaced with:

     a.opAssign(b);

 not:

     a = a.opAssign(b);

 The return value of opAssign comes in to play with:

     c = a = b;

 which is rewritten as:

     c = a.opAssign(b);
Doh! Doh! Doh! My bad; I saw this elsewhere and just assumed it would operate correctly. The syntax, however, is very clean. Importantly, it supports the unification or /centralization/ of all those 'new' invocations. I'd go so far as to say such a syntax could represent a bridge between OO and scripting: ---- String s = "mystring"; ---- ---- File f = "/foo/bar.d"; ---- ---- Regex r = "^(.*)$"; ---- There's a fairly wide range of simple applicability for this kinda' thing. Would be great if static opAssign() could support this, or some other operator were enabled? How about it?
One note: an operator is suggested so that structs could take advantage of this also. Otherwise, some kind of 'property' assignment for a ctor might have done the trick?
Feb 19 2007
prev sibling parent reply Walter Bright <newshound digitalmars.com> writes:
kris wrote:
 The syntax, however, is very clean. Importantly, it supports the 
 unification or /centralization/ of all those 'new' invocations. I'd go 
 so far as to say such a syntax could represent a bridge between OO and 
 scripting:
 
 ----
 String s = "mystring";
 ----
 
 ----
 File f = "/foo/bar.d";
 ----
 
 ----
 Regex r = "^(.*)$";
 ----
 
 There's a fairly wide range of simple applicability for this kinda' 
 thing. Would be great if static opAssign() could support this, or some 
 other operator were enabled?
 
 How about it?
I don't get it. Exactly what transformation are you looking for?
Feb 19 2007
next sibling parent reply kris <foo bar.com> writes:
Walter Bright wrote:
 kris wrote:
 
 The syntax, however, is very clean. Importantly, it supports the 
 unification or /centralization/ of all those 'new' invocations. I'd go 
 so far as to say such a syntax could represent a bridge between OO and 
 scripting:

 ----
 String s = "mystring";
 ----

 ----
 File f = "/foo/bar.d";
 ----

 ----
 Regex r = "^(.*)$";
 ----

 There's a fairly wide range of simple applicability for this kinda' 
 thing. Would be great if static opAssign() could support this, or some 
 other operator were enabled?

 How about it?
I don't get it. Exactly what transformation are you looking for?
Something that combines the decl with an assignment, with a more concise syntax than 'new', that works for both struct and class, and with the side-benefit of isolating the code required to instantiate an object instance (e.g. the codegen required for "x = new Blah" is located in one spot rather than being repeated multiple times). For example, this type of function might be added to a class (for want of a better name): static File opDecl (char[] foo) { return new File (foo); } And this one might be added to a struct: static MyStruct opDecl (int[] x) { MyStruct s; s.list = x; return s; } In both cases, assignment to a decl would invoke the opDecl() and assign the result: File f = "myfilePath"; MyStruct s = [1, 2, 3]; It's a shorthand notation in both cases, and happens to reduce the distinction between class & struct also? In the class case, it eliminates the repeated codegen associated with "new" too. There should be no conflict with custom allocators either, since the opDecl() is just a convenience wrapper around the existing mechanisms; right? In short, this is a shorthand ctor, that could work for both class and struct?
Feb 19 2007
parent reply Walter Bright <newshound digitalmars.com> writes:
kris wrote:
 In short, this is a shorthand ctor, that could work for both class and 
 struct?
The whole constructor thing for structs will get revisited, and then it would be good to deal with this.
Feb 19 2007
parent kris <foo bar.com> writes:
Walter Bright wrote:
 kris wrote:
 
 In short, this is a shorthand ctor, that could work for both class and 
 struct?
The whole constructor thing for structs will get revisited, and then it would be good to deal with this.
ok, thx
Feb 19 2007
prev sibling parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Walter Bright wrote:
 kris wrote:
 The syntax, however, is very clean. Importantly, it supports the 
 unification or /centralization/ of all those 'new' invocations. I'd go 
 so far as to say such a syntax could represent a bridge between OO and 
 scripting:

 ----
 String s = "mystring";
 ----

 ----
 File f = "/foo/bar.d";
 ----

 ----
 Regex r = "^(.*)$";
 ----

 There's a fairly wide range of simple applicability for this kinda' 
 thing. Would be great if static opAssign() could support this, or some 
 other operator were enabled?

 How about it?
I don't get it. Exactly what transformation are you looking for?
He wants String s = "mystring"; To call something like: static String opConstruct(char[] str) { return new String(str); } So that 's' get's initialized with a freshly allocated String. With the current opAssign stuff you have to do: String s = new String; s = "mystring"; I've felt this too. After you add an opCast, things like s="mystring" become valid, and soon after that you start to expect String s = "mystring" to work too. --bb
Feb 19 2007
parent Bill Baxter <dnewsgroup billbaxter.com> writes:
Bill Baxter wrote:
 Walter Bright wrote:
 kris wrote:
 The syntax, however, is very clean. Importantly, it supports the 
 unification or /centralization/ of all those 'new' invocations. I'd 
 go so far as to say such a syntax could represent a bridge between OO 
 and scripting:

 ----
 String s = "mystring";
 ----

 ----
 File f = "/foo/bar.d";
 ----

 ----
 Regex r = "^(.*)$";
 ----

 There's a fairly wide range of simple applicability for this kinda' 
 thing. Would be great if static opAssign() could support this, or 
 some other operator were enabled?

 How about it?
I don't get it. Exactly what transformation are you looking for?
He wants String s = "mystring"; To call something like: static String opConstruct(char[] str) { return new String(str); } So that 's' get's initialized with a freshly allocated String. With the current opAssign stuff you have to do: String s = new String; s = "mystring"; I've felt this too. After you add an opCast,
Correction: I meant opAssign.
things like s="mystring" 
 become valid, and soon after that you start to expect String s = 
 "mystring" to work too.
I agree with kris that such a thing would be nice to have. If a=b works it seems like "Type a = b" should work too. --bb
Feb 19 2007