digitalmars.D.learn - struct postblit not called, but still destructed
- Lemonfiend (54/54) Jan 19 2014 When a struct is passed to a function as argument, it is first
- Lemonfiend (1/1) Jan 19 2014 I just tried the new beta, and the issue remains.
- Benjamin Thaut (5/55) Jan 19 2014 Yes this looks like a bug to me. Please file a bug report at
- monarch_dodra (57/61) Jan 19 2014 Here is a reduced case:
- monarch_dodra (17/18) Jan 19 2014 https://d.puremagic.com/issues/show_bug.cgi?id=11952
- Maxim Fomin (5/13) Jan 20 2014 It is rather bug than ER because recently there was work to
When a struct is passed to a function as argument, it is first copied and at the end destructed. But in the following code it is not copied, yet still destructed? module main; import std.stdio; struct C { A[] _objs; this(A[] objs...) { writeln(` C this()`); _objs = objs; // A.this(this) is not called // yet A.~this IS called } } struct B { A sup; alias sup this; this(A a) { writeln(count, ` B this()`); sup = a; } } struct A { static int count; this(int n) { count++; writeln(count, ` A this()`); } this(this) { count++; writeln(count, ` A this(this)`); } ~this() { count--; writeln(count, ` A ~this()`); } } void main() { A a = A(1); writeln(a.count == 1); B b = B(a); writeln(a.count == 2); C c = C(b); writeln(a.count == 3); }
Jan 19 2014
Am 19.01.2014 18:48, schrieb Lemonfiend:import std.stdio; struct C { A[] _objs; this(A[] objs...) { writeln(` C this()`); _objs = objs; // A.this(this) is not called // yet A.~this IS called } } struct B { A sup; alias sup this; this(A a) { writeln(count, ` B this()`); sup = a; } } struct A { static int count; this(int n) { count++; writeln(count, ` A this()`); } this(this) { count++; writeln(count, ` A this(this)`); } ~this() { count--; writeln(count, ` A ~this()`); } } void main() { A a = A(1); writeln(a.count == 1); B b = B(a); writeln(a.count == 2); C c = C(b); writeln(a.count == 3); }Yes this looks like a bug to me. Please file a bug report at https://d.puremagic.com/issues/ Kind Regards Benjamin Thaut
Jan 19 2014
On Sunday, 19 January 2014 at 19:24:23 UTC, Benjamin Thaut wrote:Yes this looks like a bug to me. Please file a bug report at https://d.puremagic.com/issues/ Kind Regards Benjamin ThautHere is a reduced case: //---- import std.stdio; struct B { A sup; this(A a) { writeln("Here"); sup = a; writeln("There"); } } struct A { static int count; this(int n) { writeln("A.this()"); } this(this) { writeln("A.this(this)"); } ~this() { writeln("A.~this()"); } } void main() { A a = A(1); writeln("Start"); B b = B(a); writeln("End"); } //---- A.this() Start A.this(this) Here A.this(this) //!!! A.~this() //!!! There A.~this() End A.~this() A.~this() //---- I think the behavior is not *strictly* incorrect: When you write: sup = a; it triggers a postblit of "a" into "sup". To do said postblit, you destroy sup. It's the way it works :/ Arguably, since it is initialization, we could avoid the destruction altogether, but it's not strictly *wrong*. I'll file it as an ER, and try to get Kenji on it.
Jan 19 2014
On Sunday, 19 January 2014 at 20:46:06 UTC, monarch_dodra wrote:I'll file it as an ER, and try to get Kenji on it.https://d.puremagic.com/issues/show_bug.cgi?id=11952 As a workaround, it is usually recommended in the destructor to try to detect "initial state", and do nothing in such cases. This is generally recommended anyways, since the .init state could mess up your count: void main() { //Scope { A a; //No increment count }//Destruction assert(A.count == 0); //Fails } I'd say disabling "this()" would help, but in this case, your example code still fails... I'll bump the report to bug because of this.
Jan 19 2014
On Sunday, 19 January 2014 at 20:46:06 UTC, monarch_dodra wrote:I think the behavior is not *strictly* incorrect: When you write: sup = a; it triggers a postblit of "a" into "sup". To do said postblit, you destroy sup. It's the way it works :/ Arguably, since it is initialization, we could avoid the destruction altogether, but it's not strictly *wrong*. I'll file it as an ER, and try to get Kenji on it.It is rather bug than ER because recently there was work to recognize such cases (initial assignment in constructors) as initialization, not just assignment. However I am not sure here because these changes were not documented properly.
Jan 20 2014