[Issue 19430] wrong code for `this =`, corrupted memory issue
https://issues.dlang.org/show_bug.cgi?id=19430 --- Comment #11 from Илья Ярошенко --- I am starting to dig deeper since I have more code that uses RC with D. The first one issue is https://issues.dlang.org/show_bug.cgi?id=19774 The second one related to generic `=` operator, still needs to be reduced. --
[Issue 19430] wrong code for `this =`, corrupted memory issue
https://issues.dlang.org/show_bug.cgi?id=19430 Илья Ярошенко changed: What|Removed |Added Resolution|LATER |INVALID --
[Issue 19430] wrong code for `this =`, corrupted memory issue
https://issues.dlang.org/show_bug.cgi?id=19430 --- Comment #10 from Stanislav Blinov --- To be fair, calling assignment on an instance that hasn't been yet constructed (i.e. constructor didn't return) isn't the best of ideas. I know Phobos is doing this in places, but it's something that should really, really be avoided. --
[Issue 19430] wrong code for `this =`, corrupted memory issue
https://issues.dlang.org/show_bug.cgi?id=19430 Илья Ярошенко changed: What|Removed |Added Status|REOPENED|RESOLVED Resolution|--- |LATER --- Comment #9 from Илья Ярошенко --- Ok, requires more research --
[Issue 19430] wrong code for `this =`, corrupted memory issue
https://issues.dlang.org/show_bug.cgi?id=19430 --- Comment #8 from Stanislav Blinov --- Working example: https://run.dlang.io/is/dnxQNx --
[Issue 19430] wrong code for `this =`, corrupted memory issue
https://issues.dlang.org/show_bug.cgi?id=19430 --- Comment #7 from Stanislav Blinov --- What's going on is (pseudo-code) this: c = S(S.init).opAssign(S.sum(1, 2)); The opAssign is implicitly generated. Two instances are constructed in-place, one is 'main.s', the other is the argument to opAssign, no copies are made, no postblits are called. But then the argument of opAssign is getting destructed, and decrements count to 0. So 0 is the correct output here. For it to be 1, you *need* an explicit opAssign: void opAssign(S rhs) { if (ptr && *ptr) atomicOp!"+="(*ptr, 1); } If it were a C++ std::shared_ptr kind of reference count (i.e. not a static counter), then you'd need this kind of opAssign: void opAssign(S rhs) { import std.algorithm.mutation : swap; swap(ptr, rhs.ptr); } --
[Issue 19430] wrong code for `this =`, corrupted memory issue
https://issues.dlang.org/show_bug.cgi?id=19430 Илья Ярошенко changed: What|Removed |Added Status|RESOLVED|REOPENED Resolution|FIXED |--- --
[Issue 19430] wrong code for `this =`, corrupted memory issue
https://issues.dlang.org/show_bug.cgi?id=19430 Илья Ярошенко changed: What|Removed |Added Status|REOPENED|RESOLVED Resolution|--- |FIXED --
[Issue 19430] wrong code for `this =`, corrupted memory issue
https://issues.dlang.org/show_bug.cgi?id=19430 Илья Ярошенко changed: What|Removed |Added Status|RESOLVED|REOPENED Resolution|INVALID |--- --
[Issue 19430] wrong code for `this =`, corrupted memory issue
https://issues.dlang.org/show_bug.cgi?id=19430 --- Comment #6 from Илья Ярошенко --- (In reply to Stanislav Blinov from comment #5) > I'll close this for now, please reopen as needed. import core.atomic; import core.stdc.stdio; import core.stdc.stdlib; struct S { static shared int* ptr; this(int i) { ptr = cast(shared int*) malloc(4); *ptr = 1; } pragma(inline, false) this(this) { if (ptr && *ptr) atomicOp!"+="(*ptr, 1); } ~this() { if (ptr && *ptr) atomicOp!"-="(*ptr, 1); } this(int r, int e) { this = sum(r, e); } static S sum(int r, int e) { return S(r + e); } } void main() { auto s = S(1, 2); import std.stdio; writeln(*s.ptr); } output: 0 expected: 1 --
[Issue 19430] wrong code for `this =`, corrupted memory issue
https://issues.dlang.org/show_bug.cgi?id=19430 Stanislav Blinov changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |INVALID --- Comment #5 from Stanislav Blinov --- I'll close this for now, please reopen as needed. --
[Issue 19430] wrong code for `this =`, corrupted memory issue
https://issues.dlang.org/show_bug.cgi?id=19430 --- Comment #4 from Илья Ярошенко --- Inter(In reply to Stanislav Blinov from comment #3) > You forgot a `puts` in the two-argument constructor. There are exactly two > instances being constructed. One by returning from `sum`, the other one is > `c` in main. First "d" in output is from assignment, second is on exiting > main. All seems quite legit, i.e. WAD. Ah, yes. In the same time, I am sure there is definitely an issue. Will try to find better code example --
[Issue 19430] wrong code for `this =`, corrupted memory issue
https://issues.dlang.org/show_bug.cgi?id=19430 --- Comment #3 from Stanislav Blinov --- You forgot a `puts` in the two-argument constructor. There are exactly two instances being constructed. One by returning from `sum`, the other one is `c` in main. First "d" in output is from assignment, second is on exiting main. All seems quite legit, i.e. WAD. --
[Issue 19430] wrong code for `this =`, corrupted memory issue
https://issues.dlang.org/show_bug.cgi?id=19430 --- Comment #2 from Илья Ярошенко --- The number of the constructor (including postblits) must match the number of destructors. Assume you have a reference counted member. Then the code in the issue will cause a corrupted memory error. --
[Issue 19430] wrong code for `this =`, corrupted memory issue
https://issues.dlang.org/show_bug.cgi?id=19430 Stanislav Blinov changed: What|Removed |Added CC||stanislav.bli...@gmail.com --- Comment #1 from Stanislav Blinov --- I don't see wrong code here. `this = ` is `this.opAssign(rhs)`. That opAssign in this case is implicit, copy is omitted. Add void opAssign(S rhs) { i = rhs.i; puts("a"); } the output will be c a d d --
[Issue 19430] wrong code for `this =`, corrupted memory issue
https://issues.dlang.org/show_bug.cgi?id=19430 Илья Ярошенко changed: What|Removed |Added Keywords||wrong-code Summary|wrong code for `this =` |wrong code for `this =`, ||corrupted memory issue --