digitalmars.D - opAssign(int) necessitates this(this) for automatic opAssign to work
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (37/37) Dec 26 2009 I've tested the following with dmd 2.037.
- Simen kjaeraas (9/24) Dec 26 2009 ny =
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (10/32) Dec 26 2009 post-blit is when an object is constructed from another one. The above
- Simen kjaeraas (18/53) Dec 27 2009 ve
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (31/84) Dec 27 2009 Doesn't allowing user defined post-blit and opAssign makes them not so
I've tested the following with dmd 2.037. The compiler generated opAssign is disabled by the definition of opAssign(int). The compiler rejects the following assignment operation. (The error message is in the comment below.) Is this by design? When I also define post-blit, the compiler generated opAssign is available again and seems to work correctly. (My struct doesn't have any members for brevity.) The program below compiles when this(this) is provided. void main() { S s0; s0 = s0; // ERROR } struct S { /* 1) Define just opAssign(int); the compiler rejects the code: Error: function deneme.S.opAssign (int) is not callable using argument types (S) Error: cannot implicitly convert expression (s0) of type S to int */ ref S opAssign(int) { return this; } /* 2) Uncomment post-blit; the above error disappears and the compiler generated opAssign works as expected */ // this(this) // {} } What is the logic behind it? Thank you, Ali
Dec 26 2009
On Sun, 27 Dec 2009 01:42:07 +0100, Ali =C3=87ehreli <acehreli yahoo.com=wrote:I've tested the following with dmd 2.037. The compiler generated opAssign is disabled by the definition of =opAssign(int). The compiler rejects the following assignment operation=. =(The error message is in the comment below.) Is this by design? When I also define post-blit, the compiler generated opAssign is =available again and seems to work correctly. (My struct doesn't have a=ny =members for brevity.) The program below compiles when this(this) is provided. void main() { S s0; s0 =3D s0; // ERROR }This piece of code does post-blit, not opAssign(int). Try defining opAssign(S). That should work here. The problem is, opAssign(int) takes a right-hand parameter of type int, whereas s0 =3D s0; has a rhs of type S. -- = Simen
Dec 26 2009
Simen kjaeraas wrote:On Sun, 27 Dec 2009 01:42:07 +0100, Ali Çehreli <acehreli yahoo.com>wrote:post-blit is when an object is constructed from another one. The above has two already constructed objects on both sides. So I think it is assignment.I've tested the following with dmd 2.037. The compiler generated opAssign is disabled by the definition of opAssign(int). The compiler rejects the following assignment operation. (The error message is in the comment below.) Is this by design? When I also define post-blit, the compiler generated opAssign is available again and seems to work correctly. (My struct doesn't have any members for brevity.) The program below compiles when this(this) is provided. void main() { S s0; s0 = s0; // ERROR }This piece of code does post-blit, not opAssign(int).Try defining opAssign(S). That should work here.I know; but the problem is, defining opAssign(int) disables the compiler-generated opAssign(S); which is then interestingly available again, once this(this) is defined. I just wanted to know whether there is a compiler bug in this behavior. Ali
Dec 26 2009
On Sun, 27 Dec 2009 02:23:47 +0100, Ali =C3=87ehreli <acehreli yahoo.com=wrote:Simen kjaeraas wrote: > On Sun, 27 Dec 2009 01:42:07 +0100, Ali =C3=87ehreli <acehreli yaho=o.com> =wrote: > >> I've tested the following with dmd 2.037. >> >> The compiler generated opAssign is disabled by the definition of >> opAssign(int). The compiler rejects the following assignment >> operation. (The error message is in the comment below.) >> >> Is this by design? >> >> When I also define post-blit, the compiler generated opAssign is >> available again and seems to work correctly. (My struct doesn't ha=ve>> any members for brevity.) >> >> The program below compiles when this(this) is provided. >> >> void main() >> { >> S s0; >> s0 =3D s0; // ERROR >> } > > This piece of code does post-blit, not opAssign(int). post-blit is when an object is constructed from another one. The above==has two already constructed objects on both sides. So I think it is =assignment. > Try defining opAssign(S). That should work here. I know; but the problem is, defining opAssign(int) disables the =compiler-generated opAssign(S); which is then interestingly available ==again, once this(this) is defined. I just wanted to know whether there is a compiler bug in this behavior=.AliStructs being what they are (Plain Old Data), opAssign(typeof(this)) is basically the same as this(this). In both cases, you create a copy of an= existing struct, and thus need to .dup referenced data that should be unique, and whatever else your copying function needs. If you define an opAssign, you've basically informed the compiler that this struct should only be assignable from whatever parameters opAssign takes. If you define postblit, you've said 'this struct can be constructed from another instance of the same struct', meaning it's assignable to itself. If you can't, then when would you ever do a postblit? -- = Simen
Dec 27 2009
Simen kjaeraas wrote:On Sun, 27 Dec 2009 02:23:47 +0100, Ali Çehreli <acehreli yahoo.com>wrote:Doesn't allowing user defined post-blit and opAssign makes them not so anymore? I think I read here some time ago that even copying is not blitting anymore, but a memberwhise copy. It would have to be, to support members of types that define their own this(this) anyway.Simen kjaeraas wrote: > On Sun, 27 Dec 2009 01:42:07 +0100, Ali Çehreli <acehreli yahoo.com> wrote: > >> I've tested the following with dmd 2.037. >> >> The compiler generated opAssign is disabled by the definition of >> opAssign(int). The compiler rejects the following assignment >> operation. (The error message is in the comment below.) >> >> Is this by design? >> >> When I also define post-blit, the compiler generated opAssign is >> available again and seems to work correctly. (My struct doesn't have >> any members for brevity.) >> >> The program below compiles when this(this) is provided. >> >> void main() >> { >> S s0; >> s0 = s0; // ERROR >> } > > This piece of code does post-blit, not opAssign(int). post-blit is when an object is constructed from another one. The above has two already constructed objects on both sides. So I think it is assignment. > Try defining opAssign(S). That should work here. I know; but the problem is, defining opAssign(int) disables the compiler-generated opAssign(S); which is then interestingly available again, once this(this) is defined. I just wanted to know whether there is a compiler bug in this behavior. AliStructs being what they are (Plain Old Data),opAssign(typeof(this)) is basically the same as this(this). In both cases, you create a copy of an existing struct, and thus need to .dup referenced data that should be unique, and whatever else your copying function needs.Isn't assignment two operations together: destroying the old object and constructing a new one? That brings the exception safety issue. We cannot destroy the old value before ensuring that the new value will be constructed successfully. Hence, the automatic opAssign is documented to be: S* opAssign(S s) { ... bitcopy *this into tmp ... ... bitcopy s into *this ... ... call destructor on tmp ... return this; } That is from http://digitalmars.com/d/2.0/struct.html But I suspected that that defition is not exception safe; *IF copying is not blitting anymore. If an exception is thrown during copying s into *this, then we would have a half constructed object. It was then, when I was trying to see whether the automatic assignment is exception-safe, that I discovered the behavior that I asked about.If you define an opAssign, you've basically informed the compiler that this struct should only be assignable from whatever parameters opAssign takes.Fine.If you define postblit, you've said 'this struct can be constructed from another instance of the same struct', meaning it's assignable to itself.I fail to see that post-blit and assignment are the same. And the documentation supports my understanding. Thank you very much for your help, but because you didn't explicitly say that the documentation is wrong; I continue having my doubts. :)If you can't, then when would you ever do a postblit?The operations post blit... ;) Ali
Dec 27 2009