digitalmars.D - this as lvalue?
- JMRyan (15/15) Sep 03 2010 I wouldn't have thought of "this" representing an lvalue. However, the
- bearophile (5/7) Sep 03 2010 I think it's not a bug. It's not a common need, but a method may way wan...
- Andrei Alexandrescu (3/10) Sep 03 2010 For classes this must be an rvalue.
- Jonathan M Davis (14/30) Sep 03 2010 There is no value in this being assignable in a class, but at the lower ...
- Andrei Alexandrescu (3/4) Sep 03 2010 It's very simple - make "this" the result of a hypothetical function cal...
- Jonathan M Davis (4/10) Sep 03 2010 Ah, that would do it. Though you wouldn't want to _actually_ do that in ...
- bearophile (4/5) Sep 03 2010 OK. Why?
- Andrei Alexandrescu (4/7) Sep 03 2010 If you could change this from within a method you'd pretty much ruin
- Jonathan M Davis (12/22) Sep 03 2010 On the bright side, except for the constructor, it should only change wh...
- KennyTM~ (3/17) Sep 04 2010 If 'this' is an rvalue then it is not possible to take the address
- Jonathan M Davis (3/24) Sep 04 2010 And of what possible use would taking the address of an object reference...
- Andrei Alexandrescu (3/23) Sep 04 2010 And I think you shouldn't do that either!
- JMRyan (3/7) Sep 05 2010 I reported this as issue 4819.
- Andrej Mitrovic (13/20) Sep 05 2010 Does this mean assigning to fields won't be an option anymore when using...
- Andrei Alexandrescu (4/16) Sep 05 2010 No, guys, most everything will be the same. If you can write (new Foo).x...
- bearophile (8/9) Sep 05 2010 See my bug reports/enhancement requests (about three days ago in a progr...
- Andrej Mitrovic (20/27) Sep 05 2010 ++ on that bug report.
- bearophile (4/5) Sep 06 2010 Then vote for it :-)
- Andrej Mitrovic (3/8) Sep 06 2010 Done. I only have 5 votes left though.
- Andrej Mitrovic (5/27) Sep 05 2010 Gmail likes to eat my code for some reason, it just ate two closing
- Jonathan M Davis (16/32) Sep 05 2010 No, it simply means that you won't be able to do this in a class:
- Andrej Mitrovic (18/50) Sep 05 2010 Ok, thanks. I never liked the "lvalue rvalue" names.. For example
- Jonathan M Davis (88/107) Sep 03 2010 Of course, this is an lvalue.
- Steven Schveighoffer (10/24) Sep 04 2010 Should this work?
- Andrei Alexandrescu (3/27) Sep 04 2010 The example should work, but doesn't need this to be an lvalue.
I wouldn't have thought of "this" representing an lvalue. However, the following absurdity compiles and executes flawlessly. Just don't uncomment the assignment to y.i! class Yikes { int i; this() { this = null; } } void main() { auto y = new Yikes(); // y.i = 0; } Is this a bug in the compiler (v.2.047)? Am I missing something in thinking it shouldn't be?
Sep 03 2010
JMRyan:Is this a bug in the compiler (v.2.047)? Am I missing something in thinking it shouldn't be?I think it's not a bug. It's not a common need, but a method may way want to swap this with another. In Phobos this is done on a struct, see: http://www.dsource.org/projects/phobos/browser/trunk/phobos/std/stdio.d#L324 Bye, bearophile
Sep 03 2010
On 9/3/10 16:03 CDT, bearophile wrote:JMRyan:For classes this must be an rvalue. AndreiIs this a bug in the compiler (v.2.047)? Am I missing something in thinking it shouldn't be?I think it's not a bug. It's not a common need, but a method may way want to swap this with another. In Phobos this is done on a struct, see: http://www.dsource.org/projects/phobos/browser/trunk/phobos/std/stdio.d#L324 Bye, bearophile
Sep 03 2010
On Friday 03 September 2010 14:22:46 Andrei Alexandrescu wrote:On 9/3/10 16:03 CDT, bearophile wrote:There is no value in this being assignable in a class, but at the lower level of how the functions are actually declared underneath (with them taking this as an argument), it makes perfect sense that it would work. It certainly wouldn't be bad to disallow it though, since it's pointless and is just going to cause bugs, though generally not as bad as the ones in the OP's example (since he assigned to this in the constructor). Still, I don't know how you could make it a true rvalue. You'd need the ability to pass a const reference to non-const data to do that, and D doesn't allow for that. The invisible this parameter, being a reference, is going to suffer from all of the issues with const that have been oft-discussed (though, generally what people want is a non-const reference to const data rather than a const reference to non-const data like you would need for this). - Jonathan M DavisJMRyan:For classes this must be an rvalue. AndreiIs this a bug in the compiler (v.2.047)? Am I missing something in thinking it shouldn't be?I think it's not a bug. It's not a common need, but a method may way want to swap this with another. In Phobos this is done on a struct, see: L324 Bye, bearophile
Sep 03 2010
On 9/3/10 16:33 CDT, Jonathan M Davis wrote:Still, I don't know how you could make it a true rvalue.It's very simple - make "this" the result of a hypothetical function call. Andrei
Sep 03 2010
On Friday 03 September 2010 14:38:27 Andrei Alexandrescu wrote:On 9/3/10 16:33 CDT, Jonathan M Davis wrote:Ah, that would do it. Though you wouldn't want to _actually_ do that in the generated code given how poor the inliner is. - Jonathan M DavisStill, I don't know how you could make it a true rvalue.It's very simple - make "this" the result of a hypothetical function call. Andrei
Sep 03 2010
Andrei Alexandrescu:For classes this must be an rvalue.OK. Why? Bye, bearophile
Sep 03 2010
On 9/3/10 17:16 CDT, bearophile wrote:Andrei Alexandrescu:If you could change this from within a method you'd pretty much ruin everything about object orientation. AndreiFor classes this must be an rvalue.OK. Why?
Sep 03 2010
On Friday 03 September 2010 15:18:25 Andrei Alexandrescu wrote:On 9/3/10 17:16 CDT, bearophile wrote:On the bright side, except for the constructor, it should only change what happens in that one member function and anything member functions that are called from it (or called from something that's called from it), so it's not like it's going to break everything. But really, it shouldn't work. There's no value to it. It just allows for bugs, even if you have to work at it to get them. I'm 99% certain that you can't surprised that it's possible that actually want to be able to. It's useful for structs, but for classes, it has no value. And as you say, it effectively breaks object orientation. - Jonathan M DavisAndrei Alexandrescu:If you could change this from within a method you'd pretty much ruin everything about object orientation. AndreiFor classes this must be an rvalue.OK. Why?
Sep 03 2010
On Sep 4, 10 05:22, Andrei Alexandrescu wrote:On 9/3/10 16:03 CDT, bearophile wrote:If 'this' is an rvalue then it is not possible to take the address ('&this').JMRyan:For classes this must be an rvalue. AndreiIs this a bug in the compiler (v.2.047)? Am I missing something in thinking it shouldn't be?I think it's not a bug. It's not a common need, but a method may way want to swap this with another. In Phobos this is done on a struct, see: http://www.dsource.org/projects/phobos/browser/trunk/phobos/std/stdio.d#L324 Bye, bearophile
Sep 04 2010
On Saturday 04 September 2010 01:32:03 KennyTM~ wrote:On Sep 4, 10 05:22, Andrei Alexandrescu wrote:And of what possible use would taking the address of an object reference be? - Jonathan M DavisOn 9/3/10 16:03 CDT, bearophile wrote:If 'this' is an rvalue then it is not possible to take the address ('&this').JMRyan:For classes this must be an rvalue. AndreiIs this a bug in the compiler (v.2.047)? Am I missing something in thinking it shouldn't be?I think it's not a bug. It's not a common need, but a method may way want to swap this with another. In Phobos this is done on a struct, see: L324 Bye, bearophile
Sep 04 2010
On 9/4/10 3:32 CDT, KennyTM~ wrote:On Sep 4, 10 05:22, Andrei Alexandrescu wrote:And I think you shouldn't do that either! AndreiOn 9/3/10 16:03 CDT, bearophile wrote:If 'this' is an rvalue then it is not possible to take the address ('&this').JMRyan:For classes this must be an rvalue. AndreiIs this a bug in the compiler (v.2.047)? Am I missing something in thinking it shouldn't be?I think it's not a bug. It's not a common need, but a method may way want to swap this with another. In Phobos this is done on a struct, see: http://www.dsource.org/projects/phobos/browser/trunk/phobos/std/stdio.d#L324 Bye, bearophile
Sep 04 2010
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote in news:i5rovm$1q4b$1 digitalmars.com:For classes this must be an rvalue. AndreiI reported this as issue 4819.
Sep 05 2010
Does this mean assigning to fields won't be an option anymore when using this? E.g.: class Foo { int x; int y; void changeXY(int x, int y) { this.x = x; this.y = y; } } On Sun, Sep 5, 2010 at 6:09 PM, JMRyan <nospam nospam.com> wrote:Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote in news:i5rovm$1q4b$1 digitalmars.com:For classes this must be an rvalue. AndreiI reported this as issue 4819.
Sep 05 2010
On 09/05/2010 05:02 PM, Andrej Mitrovic wrote:Does this mean assigning to fields won't be an option anymore when using this? E.g.: class Foo { int x; int y; void changeXY(int x, int y) { this.x = x; this.y = y; } }No, guys, most everything will be the same. If you can write (new Foo).x = x, then you can also write this.x = x. Try it now! Andrei
Sep 05 2010
Andrei:If you can write (new Foo).x = x, then you can also write this.x = x. Try it now!See my bug reports/enhancement requests (about three days ago in a program of mine I have added a bug that enhancement 4407 is able to avoid): Arguments and attributes with the same name http://d.puremagic.com/issues/show_bug.cgi?id=3878 Catch wrong argument<->attribute assignments in methods http://d.puremagic.com/issues/show_bug.cgi?id=4407 Bye, bearophile
Sep 05 2010
++ on that bug report. On a similar note, today I was rewriting a dsource class example because I wanted to show that you can use "this.name" to assign to fields that have the same name as a parameter. And then I accidentally made this mistake when writing a different method: class Foo { string name; void printMe() { name = "test"; writefln("printMe.name = %s, Foo.name = %s", name, this.name); } } The "name" in the printMe method was supossed to be the declaration 'string name = "test";'. But I forgot to put the type before name, and inadvertently modified the class variable name. In this case I wasn't even passing any parameters, so this is unfortunately impossible to flag as an error because using "this" is optional in D. On Mon, Sep 6, 2010 at 4:14 AM, bearophile <bearophileHUGS lycos.com> wrote:Andrei:If you can write (new Foo).x = x, then you can also write this.x = x. Try it now!See my bug reports/enhancement requests (about three days ago in a program of mine I have added a bug that enhancement 4407 is able to avoid): Arguments and attributes with the same name http://d.puremagic.com/issues/show_bug.cgi?id=3878 Bye, bearophile
Sep 05 2010
Andrej Mitrovic:++ on that bug report.Then vote for it :-) Bye, bearophile
Sep 06 2010
Done. I only have 5 votes left though. This is no democracy!! :p On Mon, Sep 6, 2010 at 12:58 PM, bearophile <bearophileHUGS lycos.com> wrote:Andrej Mitrovic:++ on that bug report.Then vote for it :-) Bye, bearophile
Sep 06 2010
Gmail likes to eat my code for some reason, it just ate two closing parantheses.. lol. On Mon, Sep 6, 2010 at 12:02 AM, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:Does this mean assigning to fields won't be an option anymore when using =this?E.g.: class Foo { =A0 =A0int x; =A0 =A0int y; =A0 =A0void changeXY(int x, int y) =A0 =A0{ =A0 =A0 =A0 =A0this.x =3D x; =A0 =A0 =A0 =A0this.y =3D y; =A0 =A0} } On Sun, Sep 5, 2010 at 6:09 PM, JMRyan <nospam nospam.com> wrote:Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote in news:i5rovm$1q4b$1 digitalmars.com:For classes this must be an rvalue. AndreiI reported this as issue 4819.
Sep 05 2010
On Sunday 05 September 2010 15:02:10 Andrej Mitrovic wrote:Does this mean assigning to fields won't be an option anymore when using this? E.g.: class Foo { int x; int y; void changeXY(int x, int y) { this.x = x; this.y = y; } }No, it simply means that you won't be able to do this in a class: this = new MyObj(); In C++, this is a const pointer to non-const data in non-const functions and a const pointer to const data in const functions. The problem is that due to how D deals with const and references, you can't have this be a const reference to non-const data. And with the current implementation, that means that you can reassign this. Now, that's setting a local variable, so it only affects that function and any other member functions that it calls, but it's still not a good thing. If this in classes becomes an rvalue semantically-speaking (regardless of how its done under the hood), then you won't be able to assign to it anymore. But you should still be able to assign to anything that you get from it. Remember that this.x is dereferencing the this reference to get at the memory where x is. Whether you can assign to this is irrelevant for that. It's not trying to do anything to this itself, just what it refers to. - Jonathan M Davis
Sep 05 2010
Ok, thanks. I never liked the "lvalue rvalue" names.. For example http://en.wikipedia.org/wiki/Value_%28computer_science%29 l-value, non-lvalue, rvalue, nonlvalue.. bleh. It's the same thing as when I see "mutable, non-immutable, non-mutable, immutable" sprinkled with a few tripple negatives all around in a piece of text. /non-non-rant On Mon, Sep 6, 2010 at 12:46 AM, Jonathan M Davis <jmdavisprog gmail.com> w= rote:On Sunday 05 September 2010 15:02:10 Andrej Mitrovic wrote:and aDoes this mean assigning to fields won't be an option anymore when using this? E.g.: class Foo { =A0 =A0 int x; =A0 =A0 int y; =A0 =A0 void changeXY(int x, int y) =A0 =A0 { =A0 =A0 =A0 =A0 this.x =3D x; =A0 =A0 =A0 =A0 this.y =3D y; =A0 =A0 } }No, it simply means that you won't be able to do this in a class: this =3D new MyObj(); In C++, this is a const pointer to non-const data in non-const functions =const pointer to const data in const functions. The problem is that due t=o how Ddeals with const and references, you can't have this be a const reference=tonon-const data. And with the current implementation, that means that you =canreassign this. Now, that's setting a local variable, so it only affects t=hatfunction and any other member functions that it calls, but it's still not=a goodthing. If this in classes becomes an rvalue semantically-speaking (regard=less ofhow its done under the hood), then you won't be able to assign to it anym=ore.But you should still be able to assign to anything that you get from it. Remember that this.x is dereferencing the this reference to get at the me=morywhere x is. Whether you can assign to this is irrelevant for that. It's n=ottrying to do anything to this itself, just what it refers to. - Jonathan M Davis
Sep 05 2010
On Friday 03 September 2010 13:22:51 JMRyan wrote:I wouldn't have thought of "this" representing an lvalue. However, the following absurdity compiles and executes flawlessly. Just don't uncomment the assignment to y.i! class Yikes { int i; this() { this = null; } } void main() { auto y = new Yikes(); // y.i = 0; } Is this a bug in the compiler (v.2.047)? Am I missing something in thinking it shouldn't be?Of course, this is an lvalue. 1. Think about a struct for a moment, rather than a class. It's a value type. Assigning to this inside a struct would change the struct's value. In some circumstances, it would make perfect sense to do this. Assigning it to the struct's init property to reset it would be a prime example. 2. Think about what a member function _really_ looks like. The member function printM() in this class here class A { int _x; void printMe() { writeln(x); } } really looks like this void printMe(A this, printMe()) { writeln(this.x); } If you were to set this to null in printMe(), what would it do? Nothing. You just set a function parameter to null. Sure, after that, this be null _within that function_, but it shouldn't be null after that that because the actual object that this points to still exists, and when its reference gets passed to other member functions, those won't be null, because you just set the local variable to null. For instance, this program runs just fine: import std.stdio; class A { int _x; this(int x) { _x = x; } void print() { writeln(_x); } void nullifyMe() { this = null; } } void main() { auto a = new A(13); a.print(); a.nullifyMe(); a.print(); } It prints 13 13 Now, _your_ program bombs. However, I believe that that's because you assigned null to this in the _constructor_. My guess is that internally, your constructor looks something like this: Yikes this(Yikes this) { this = null; return this; } When this is called, its member variables (namely i) have been initialized, and its initial state is passed to the constructor to further do whatever stuff that you want your constructor to do. It then likely return null, which is what you get from new() and is what is assigned to your local variable y. So, y is then null. The Yikes object that you just created still exists. It's floating around in memory. It's just that you can't get at it. If you try this instead: import std.stdio; Yikes global; class Yikes { int i; this() { global = this; this = null; } } void main() { auto y = new Yikes(); global.i = 1; writeln(global.i); } it works and prints 1. You could even get rid of the "auto y = " part. So, this is most definitely an lvalue. It's a bit stupid to assign null to it - especially in the constructor - but it makes perfect sense that it works. And in some circumstances, it makes perfect sense to do so (though not with classes since all it would ever affect would be the local variable and any member functions that called from that member function). - Jonathan M Davis
Sep 03 2010
Andrei Alexandrescu Wrote:On 9/3/10 16:03 CDT, bearophile wrote:Should this work? class C { int x; void opAssign(int n) {x = n;} void foo(int n) {this = n;} } I agree this should not be rebindable. But it has to be an lvalue. -SteveJMRyan:For classes this must be an rvalue. AndreiIs this a bug in the compiler (v.2.047)? Am I missing something in thinking it shouldn't be?I think it's not a bug. It's not a common need, but a method may way want to swap this with another. In Phobos this is done on a struct, see: http://www.dsource.org/projects/phobos/browser/trunk/phobos/std/stdio.d#L324 Bye, bearophile
Sep 04 2010
On 09/04/2010 10:41 AM, Steven Schveighoffer wrote:Andrei Alexandrescu Wrote:The example should work, but doesn't need this to be an lvalue. AndreiOn 9/3/10 16:03 CDT, bearophile wrote:Should this work? class C { int x; void opAssign(int n) {x = n;} void foo(int n) {this = n;} } I agree this should not be rebindable. But it has to be an lvalue. -SteveJMRyan:For classes this must be an rvalue. AndreiIs this a bug in the compiler (v.2.047)? Am I missing something in thinking it shouldn't be?I think it's not a bug. It's not a common need, but a method may way want to swap this with another. In Phobos this is done on a struct, see: http://www.dsource.org/projects/phobos/browser/trunk/phobos/std/stdio.d#L324 Bye, bearophile
Sep 04 2010