digitalmars.D.learn - Struct inheritance
- amber (8/8) Feb 24 2015 Hi,
- Tobias Pankrath (12/18) Feb 24 2015 No runtime polymorphism, but a kind of sub typing via alias this.
- amber (4/26) Feb 24 2015 Thank you Tobias I get it now.
- ketmar (10/17) Feb 24 2015 there is no "copy constructor" in D. structs are copied by `memcpy()`,=2...
- ketmar (4/25) Feb 24 2015 oops. of course, you already has a struct for `opAssign` -- it need=20
- ketmar (4/14) Feb 24 2015 p.s. sometimes compiler can use "move" instead of "copy" for structures....
- H. S. Teoh via Digitalmars-d-learn (55/73) Feb 24 2015 Yes, basically, D structs are value types, and quite unlike C++ structs.
Hi, Is it possible in D to have inheritance using value types, i.e. structs? Also I don't quite understand how copy ctors work in D. Do I need to implement opAssign(S other) {}, or this(this) {} and what's the difference between these two? Thanks, Amber
Feb 24 2015
On Tuesday, 24 February 2015 at 12:05:51 UTC, amber wrote:Hi, Is it possible in D to have inheritance using value types, i.e. structs?No runtime polymorphism, but a kind of sub typing via alias this. struct S { void foo() { writeln("S.foo"); } struct T { S s; alias s this; } T t; t.foo(); // prints S.fooAlso I don't quite understand how copy ctors work in D. Do I need to implement opAssign(S other) {}, or this(this) {} and what's the difference between these two?If available, opAssign will be used in an assignment like x = y; You're custom opAssign can take arbitrary parameter types, so typeof(y) does not have to be typeof(x). postblit is used for copy construction. This could be assignment if no opAssign is provided (not sure about this), but also e.g. passing parameter by value or returning from a function.
Feb 24 2015
On Tuesday, 24 February 2015 at 12:16:43 UTC, Tobias Pankrath wrote:On Tuesday, 24 February 2015 at 12:05:51 UTC, amber wrote:Thank you Tobias I get it now. /amberHi, Is it possible in D to have inheritance using value types, i.e. structs?No runtime polymorphism, but a kind of sub typing via alias this. struct S { void foo() { writeln("S.foo"); } struct T { S s; alias s this; } T t; t.foo(); // prints S.fooAlso I don't quite understand how copy ctors work in D. Do I need to implement opAssign(S other) {}, or this(this) {} and what's the difference between these two?If available, opAssign will be used in an assignment like x = y; You're custom opAssign can take arbitrary parameter types, so typeof(y) does not have to be typeof(x). postblit is used for copy construction. This could be assignment if no opAssign is provided (not sure about this), but also e.g. passing parameter by value or returning from a functions
Feb 24 2015
On Tue, 24 Feb 2015 12:05:50 +0000, amber wrote:Hi, =20 Is it possible in D to have inheritance using value types, i.e. structs? =20 Also I don't quite understand how copy ctors work in D. Do I need to implement opAssign(S other) {}, or this(this) {} and what's the difference between these two?there is no "copy constructor" in D. structs are copied by `memcpy()`,=20 and then compiler calls "postblit" aka `this(this)`. it may seem like=20 constructor, but it's not. it's a "fixup", that fixes inconsistencies=20 that are left by `memcpy()`. i.e. when postblit is called, structure is=20 already copied. and `opAssign` is... well, overloading of "=3D" operator. it has to=20 manually create a structure copy and manually copy everything you need.=20 and it will never be called by compiler "behind the scenes", like=20 postblit.=
Feb 24 2015
On Tue, 24 Feb 2015 18:19:39 +0000, ketmar wrote:On Tue, 24 Feb 2015 12:05:50 +0000, amber wrote: =20oops. of course, you already has a struct for `opAssign` -- it need=20 `this` after all! ;-) but no automatic copying. it's just a function=20 call, nothing magic here.=Hi, =20 Is it possible in D to have inheritance using value types, i.e. structs? =20 Also I don't quite understand how copy ctors work in D. Do I need to implement opAssign(S other) {}, or this(this) {} and what's the difference between these two?=20 there is no "copy constructor" in D. structs are copied by `memcpy()`, and then compiler calls "postblit" aka `this(this)`. it may seem like constructor, but it's not. it's a "fixup", that fixes inconsistencies that are left by `memcpy()`. i.e. when postblit is called, structure is already copied. =20 and `opAssign` is... well, overloading of "=3D" operator. it has to manually create a structure copy and manually copy everything you need. and it will never be called by compiler "behind the scenes", like postblit.
Feb 24 2015
On Tue, 24 Feb 2015 12:05:50 +0000, amber wrote:Hi, =20 Is it possible in D to have inheritance using value types, i.e. structs? =20 Also I don't quite understand how copy ctors work in D. Do I need to implement opAssign(S other) {}, or this(this) {} and what's the difference between these two? =20 Thanks, Amberp.s. sometimes compiler can use "move" instead of "copy" for structures.=20 in this case it will not call postblit. so if you have some fields in=20 your struct that depends of the structure address... you're in trouble.=
Feb 24 2015
On Tue, Feb 24, 2015 at 06:22:05PM +0000, ketmar via Digitalmars-d-learn wrote:On Tue, 24 Feb 2015 12:05:50 +0000, amber wrote:Yes, basically, D structs are value types, and quite unlike C++ structs. It's a trap to assume C++-like semantics for D structs, because they are actually very different beasts. D structs should not rely on their own address remaining static, because move semantics will cause problems, for example: struct S { int x; int* p; this(int _x) { x = _x; p = &x; // uh-oh } void method() { *p++; // by the time this runs, the struct may // have moved } } S makeStruct() { return S(1); } void main() { auto s = makeStruct(); s.method(); assert(s.x == 2); // KABOOM } The problem is that returning S from makeStruct() makes a bitwise copy of the struct into main's local variable s, which has a different address than the one created in makeStruct(). But s.p still points to the old address of s.x, which is now pointing to invalid memory. For even more fun, do this: void checkItOut(int x, S* s) { assert(x == 10); s.method(); assert(x == 10); // KABOOM } void main() { auto s = makeStruct(); s.method(); checkItOut(10, &s); } Depending on the specifics of your platform, the second assert in checkItOut() may fail, because s.method(), via the stale pointer s.p, will overwrite the stack location where the original s.x was (but which has gone out of scope and is now invalid), and that old location is now being used for one of the parameters of checkItOut(). So calling s.method() will silently corrupt the stack where the parameter is passed. tl;dr, the moral of the story is, don't rely on the address of structs in D staying the same, unless you REALLY know what you're doing. And even then, you're just 1/8 of an inch away from shooting yourself in the foot. T -- All problems are easy in retrospect.Hi, Is it possible in D to have inheritance using value types, i.e. structs? Also I don't quite understand how copy ctors work in D. Do I need to implement opAssign(S other) {}, or this(this) {} and what's the difference between these two? Thanks, Amberp.s. sometimes compiler can use "move" instead of "copy" for structures. in this case it will not call postblit. so if you have some fields in your struct that depends of the structure address... you're in trouble.
Feb 24 2015