www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Fighting with alias this: bugs or features?

reply osa <osa aso.osa> writes:
Every time I'm trying to use alias this (which looks like a nice 
feature, on paper), I end up with problems. This is the most recent one 
(dmd v2.049):
------
struct Foo {}
class Bar {
     Foo foo_;
     alias foo_ this;
}

void main() {
     auto a = new Bar;
     auto b = a;
     a = null; // fails -- Error: cannot implicitly convert expression 
(null) of type void* to Foo
}
------
There are plenty of 'alias this' issues in Bugzilla, but I cannot find 
this particular problem there. So is this a bug or feature? The language 
spec does not help do decide...
Oct 26 2010
next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Tuesday, October 26, 2010 09:35:21 osa wrote:
 Every time I'm trying to use alias this (which looks like a nice
 feature, on paper), I end up with problems. This is the most recent one
 (dmd v2.049):
 ------
 struct Foo {}
 class Bar {
      Foo foo_;
      alias foo_ this;
 }
 
 void main() {
      auto a = new Bar;
      auto b = a;
      a = null; // fails -- Error: cannot implicitly convert expression
 (null) of type void* to Foo
 }
 ------
 There are plenty of 'alias this' issues in Bugzilla, but I cannot find
 this particular problem there. So is this a bug or feature? The language
 spec does not help do decide...

If you can't find a bug report for it, report it. I don't see how it could possibly be a feature that null couldn't be converted. Any pointer or reference type should be assignable to null. And in general, it's probably better to report a bug if you're not sure. If it's not valid, it'll get closed, but odds are that it's something that needs to be fixed. - Jonathan M Davis
Oct 26 2010
parent reply =?UTF-8?B?IkrDqXLDtG1lIE0uIEJlcmdlciI=?= <jeberger free.fr> writes:
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Jonathan M Davis wrote:
 On Tuesday, October 26, 2010 09:35:21 osa wrote:
 Every time I'm trying to use alias this (which looks like a nice
 feature, on paper), I end up with problems. This is the most recent on=


 (dmd v2.049):
 ------
 struct Foo {}
 class Bar {
      Foo foo_;
      alias foo_ this;
 }

 void main() {
      auto a =3D new Bar;
      auto b =3D a;
      a =3D null; // fails -- Error: cannot implicitly convert expressi=


 (null) of type void* to Foo
 }
 ------
 There are plenty of 'alias this' issues in Bugzilla, but I cannot find=


 this particular problem there. So is this a bug or feature? The langua=


 spec does not help do decide...

If you can't find a bug report for it, report it. I don't see how it co=

 possibly be a feature that null couldn't be converted. Any pointer or r=

 type should be assignable to null. And in general, it's probably better=

 report a bug if you're not sure. If it's not valid, it'll get closed, b=

 are that it's something that needs to be fixed.
=20

reported. My guess would be that the issue is with the "auto a =3D new Bar" line: I would bet that this gets interpreted as "Foo a =3D new Bar" instead of what we expect ("Bar a =3D new Bar"). If I'm right, then the "a =3D null" line is indeed an error: since Foo is a struct and structs are value types, you cannot affect "null" to a variable of type Foo... Jerome --=20 mailto:jeberger free.fr http://jeberger.free.fr Jabber: jeberger jabber.fr
Oct 26 2010
parent osa <osa aso.osa> writes:
On 10/26/2010 03:22 PM, "Jérôme M. Berger" wrote:
 	I'm not sure that the problem is on the line where the error is
 reported. My guess would be that the issue is with the "auto a = new
 Bar" line: I would bet that this gets interpreted as "Foo a = new
 Bar" instead of what we expect ("Bar a = new Bar"). If I'm right,
 then the "a = null" line is indeed an error: since Foo is a struct
 and structs are value types, you cannot affect "null" to a variable
 of type Foo...

No, that's not the case. Here is an updated test case, without any auto's: ----- struct Foo {} class Bar { Foo foo_; alias foo_ this; } void main() { Bar a; a = null; } ------ aliasthis1.d(8): Error: cannot implicitly convert expression (null) of type void* to Foo So it seems to be a real problem. I've reported it in Bugzilla: http://d.puremagic.com/issues/show_bug.cgi?id=5123
Oct 26 2010
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/26/10 11:35 CDT, osa wrote:
 Every time I'm trying to use alias this (which looks like a nice
 feature, on paper), I end up with problems. This is the most recent one
 (dmd v2.049):
 ------
 struct Foo {}
 class Bar {
 Foo foo_;
 alias foo_ this;
 }

 void main() {
 auto a = new Bar;
 auto b = a;
 a = null; // fails -- Error: cannot implicitly convert expression (null)
 of type void* to Foo
 }
 ------
 There are plenty of 'alias this' issues in Bugzilla, but I cannot find
 this particular problem there. So is this a bug or feature? The language
 spec does not help do decide...

In this particular case the decision goes both ways, and both have something going for them. You may want to submit a bug report at least to prompt us to change the documentation to clarify the behavior. A workaround is to define opAssign(Bar). Andrei
Oct 26 2010
parent reply osa <osa aso.osa> writes:
On 10/26/2010 04:46 PM, Andrei Alexandrescu wrote:
 In this particular case the decision goes both ways, and both have
 something going for them. You may want to submit a bug report at least
 to prompt us to change the documentation to clarify the behavior.
 A workaround is to define opAssign(Bar).

I do not see how defining opAssign would help here. I want to nullify local reference to a Bar instance (to let GC dispose of Bar object, for example). I do not need to change Bar or Foo. Anyway, I filed bug report: http://d.puremagic.com/issues/show_bug.cgi?id=5123
Oct 26 2010
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/26/10 16:58 CDT, osa wrote:
 On 10/26/2010 04:46 PM, Andrei Alexandrescu wrote:
 In this particular case the decision goes both ways, and both have
 something going for them. You may want to submit a bug report at least
 to prompt us to change the documentation to clarify the behavior.
 A workaround is to define opAssign(Bar).

I do not see how defining opAssign would help here. I want to nullify local reference to a Bar instance (to let GC dispose of Bar object, for example). I do not need to change Bar or Foo. Anyway, I filed bug report: http://d.puremagic.com/issues/show_bug.cgi?id=5123

Thanks. Defining opAssign for Bar will allow you to use the syntax bar = null and have it nullify the reference. (I meant "could go both ways" instead of "goes both ways".) Andrei
Oct 26 2010
parent reply osa <osa aso.osa> writes:
On 10/26/2010 05:09 PM, Andrei Alexandrescu wrote:
 Thanks. Defining opAssign for Bar will allow you to use the syntax bar =
 null and have it nullify the reference.

I feel stupid, but I do not see how to nullify the Bar reference inside of opAssign. Again, my problem is that I have Bar x = new Bar( ... ); and I want x to become null. Is there a workaround for 'cannot implicitly convert expression (null) of type void* to Foo' which does not involve low-level trickery like *cast(void**)&x = null?
Oct 26 2010
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/26/10 17:29 CDT, osa wrote:
 On 10/26/2010 05:09 PM, Andrei Alexandrescu wrote:
 Thanks. Defining opAssign for Bar will allow you to use the syntax bar =
 null and have it nullify the reference.

I feel stupid, but I do not see how to nullify the Bar reference inside of opAssign. Again, my problem is that I have Bar x = new Bar( ... ); and I want x to become null. Is there a workaround for 'cannot implicitly convert expression (null) of type void* to Foo' which does not involve low-level trickery like *cast(void**)&x = null?

Oh, I was confused. I thought you had the converse case - a class object inside a struct object. Compiler bug it is. Andrei
Oct 26 2010
prev sibling parent trx1 <trx1 nomail.com> writes:
osa Wrote:

 On 10/26/2010 05:09 PM, Andrei Alexandrescu wrote:
 Thanks. Defining opAssign for Bar will allow you to use the syntax bar =
 null and have it nullify the reference.

I feel stupid, but I do not see how to nullify the Bar reference inside of opAssign. Again, my problem is that I have Bar x = new Bar( ... ); and I want x to become null. Is there a workaround for 'cannot implicitly convert expression (null) of type void* to Foo' which does not involve low-level trickery like *cast(void**)&x = null?

A workaround is maybe struct Foo {} class Bar { Foo foo_; alias foo_ this; } void main() { auto a = new Bar; auto b = a; a = a.init; //compiles as oppose to a = null; writeln(a); // prints null } just playing around with the code, so have no explaination for the behaviour
Oct 27 2010
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 26 Oct 2010 12:35:21 -0400, osa <osa aso.osa> wrote:

 Every time I'm trying to use alias this (which looks like a nice  
 feature, on paper), I end up with problems. This is the most recent one  
 (dmd v2.049):
 ------
 struct Foo {}
 class Bar {
      Foo foo_;
      alias foo_ this;
 }

 void main() {
      auto a = new Bar;
      auto b = a;
      a = null; // fails -- Error: cannot implicitly convert expression  
 (null) of type void* to Foo
 }
 ------
 There are plenty of 'alias this' issues in Bugzilla, but I cannot find  
 this particular problem there. So is this a bug or feature? The language  
 spec does not help do decide...

alias this seems to favor the aliased member over the container itself in many cases. I'm not sure why. Alias this should be used as the last resort IMO, because when you are aliasing this, you don't want the aliased member forcefully taking control of your object. I recently filed this bug report, which has a similar feel to your problem: http://d.puremagic.com/issues/show_bug.cgi?id=4989 I think there may be others that are similar. -Steve
Oct 27 2010