Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
November 01, 2012 [Issue 8931] New: array/slice assignment causes destruction + postblit instead of opAssign | ||||
---|---|---|---|---|
| ||||
http://d.puremagic.com/issues/show_bug.cgi?id=8931 Summary: array/slice assignment causes destruction + postblit instead of opAssign Product: D Version: unspecified Platform: All OS/Version: All Status: NEW Severity: major Priority: P2 Component: DMD AssignedTo: nobody@puremagic.com ReportedBy: monarchdodra@gmail.com --- Comment #0 from monarchdodra@gmail.com 2012-11-01 10:10:38 PDT --- Basically, given two static arrays of S, or when calling array opSliceAssign, I'd expect the assignment to trigger element-wise assignment. However, what happens is that the elements of the original array are destroyed, and then postblit copies are copied over, element by element: //---- import std.algorithm; import std.stdio; struct S { int i; this(this){"post: ".writeln(i);} void opAssign(S){"opAssign".writeln();} ~this(){"dest: ".writeln(i);} } void main() { S[2] a = [S(1), S(2)]; S[2] b = [S(3), S(4)]; "begin".writeln(); a = b; "end".writeln(); } //---- post: 1 post: 2 post: 3 post: 4 begin post: 3 dest: 1 post: 4 dest: 2 end dest: 4 dest: 3 dest: 4 dest: 3 //---- opSlice/opSlice assignement will produce the same effect: //---- void main() { S[] a = [S(1), S(2)]; S[] b = [S(3), S(4)]; "begin".writeln(); a[] = b[]; "end".writeln(); } //---- destruction+postblit is not the same as opAssign, so if this is an "optimization", it is wrong. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
November 01, 2012 [Issue 8931] array/slice assignment causes destruction + postblit instead of opAssign | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarchdodra@gmail.com | http://d.puremagic.com/issues/show_bug.cgi?id=8931 Maxim Fomin <maxim@maxim-fomin.ru> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |maxim@maxim-fomin.ru --- Comment #1 from Maxim Fomin <maxim@maxim-fomin.ru> 2012-11-01 10:57:55 PDT --- I don't understand clearly this issue. You first state that when arrays are assigned you expect that this is done element-by element, but actually all elements of an array are firstly destroyed and then replaced. However output shows just the opposite: assignment is done element-by-element. Differences between two versions of main() are in the fact that elements of fixed arrays are constructed (because fixed arrays are of value semantic) and in order of assignment: in fixed array case elements are copied from the beginning and in case of dynamic arrays the operation starts from the last element. None of versions calls opAssign. I don't understand how your conclusion is based on code and what you are trying to say. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
November 01, 2012 [Issue 8931] array/slice assignment causes destruction + postblit instead of opAssign | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarchdodra@gmail.com | http://d.puremagic.com/issues/show_bug.cgi?id=8931 --- Comment #2 from monarchdodra@gmail.com 2012-11-01 11:07:07 PDT --- (In reply to comment #1) > I don't understand clearly this issue. You first state that when arrays are assigned you expect that this is done element-by element, but actually all elements of an array are firstly destroyed and then replaced. > > However output shows just the opposite: assignment is done element-by-element. Differences between two versions of main() are in the fact that elements of fixed arrays are constructed (because fixed arrays are of value semantic) and in order of assignment: in fixed array case elements are copied from the beginning and in case of dynamic arrays the operation starts from the last element. None of versions calls opAssign. I don't understand how your conclusion is based on code and what you are trying to say. I'm sorry I did not make myself clear. The issue was not about the order (I hadn't even noticed the difference between both version). The issue is that the elements in the destination array (a) are destroyed and then postblit recreated. I'd have expected to see assignments instead. I mean: //----void main() { S[2] a = [S(1), S(2)]; S[2] b = a; //Fine postblit here a[] = b[]; //But HERE, please use opAssign. } //---- -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
November 01, 2012 [Issue 8931] array/slice assignment causes destruction + postblit instead of opAssign | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarchdodra@gmail.com | http://d.puremagic.com/issues/show_bug.cgi?id=8931 --- Comment #3 from Maxim Fomin <maxim@maxim-fomin.ru> 2012-11-01 11:48:32 PDT --- (In reply to comment #2) > I mean: > //----void main() > { > S[2] a = [S(1), S(2)]; > S[2] b = a; //Fine postblit here > a[] = b[]; //But HERE, please use opAssign. > } > //---- I see now and it does make sense. But it seems to be impossible now because of how _d_arrayassign function (https://github.com/D-Programming-Language/druntime/blob/master/src/rt/arrayassign.d#L30) assigns arrays: it uses memcpy+postblit+destroy because TypeInfo class (https://github.com/D-Programming-Language/druntime/blob/master/src/object.di#L68) lacks entry related to opAssign method. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
September 05, 2013 [Issue 8931] array/slice assignment causes destruction + postblit instead of opAssign | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarchdodra@gmail.com | http://d.puremagic.com/issues/show_bug.cgi?id=8931 --- Comment #4 from monarchdodra@gmail.com 2013-09-05 00:36:55 PDT --- (In reply to comment #3) > (In reply to comment #2) > > I mean: > > //----void main() > > { > > S[2] a = [S(1), S(2)]; > > S[2] b = a; //Fine postblit here > > a[] = b[]; //But HERE, please use opAssign. > > } > > //---- > > I see now and it does make sense. But it seems to be impossible now because of > how _d_arrayassign function > (https://github.com/D-Programming-Language/druntime/blob/master/src/rt/arrayassign.d#L30) > assigns arrays: it uses memcpy+postblit+destroy because TypeInfo class > (https://github.com/D-Programming-Language/druntime/blob/master/src/object.di#L68) > lacks entry related to opAssign method. I did some extra thinking about this, and this might be invalid. While one might "expect" opAssign to be called, doing this would mean it is impossible to have a strong exception safe behavior should one of the assignements fails. Using postblit does (can[1]) guarantee that. [1]: See also http://d.puremagic.com/issues/show_bug.cgi?id=10967 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
Copyright © 1999-2021 by the D Language Foundation