digitalmars.D - Inconsistent behavior shared struct vs non-shared storage - bug?
- apz28 (57/57) Jun 02 2021 import std.stdio;
- Iain Buclaw (18/33) Jun 02 2021 I suspect this is a topic better suited to d.learn, but you are
import std.stdio; enum sharedit = false; __gshared int counter = 0; class C { } struct S { C c; this(C c) { counter++; writeln("this(): ", counter); this.c = c is null ? new C() : c; } ~this() { counter--; writeln("~this(): ", counter); } int foo() { writeln("foo(): ", counter); return 1; } } static if (sharedit) shared S s; else __gshared S s; shared static this() { writeln("shared static this(1): ", counter); static if (sharedit) s = cast(shared)S(null); else s = S(null); writeln("shared static this(2): ", counter); } void main() { writeln("main(1): ", counter); static if (sharedit) auto i = (cast()s).foo(); else auto i = s.foo(); writeln("main(2): ", counter); } /* sharedit = true shared static this(1): 0 this(): 1 ~this(): 0 shared static this(2): 0 main(1): 0 foo(): 0 main(2): 0 */ /* sharedit = false shared static this(1): 0 this(): 1 shared static this(2): 1 main(1): 1 foo(): 1 main(2): 1 */
Jun 02 2021
On Wednesday, 2 June 2021 at 12:25:54 UTC, apz28 wrote:struct S { C c; this(C c) { counter++; writeln("this(): ", counter); this.c = c is null ? new C() : c; }I suspect this is a topic better suited to d.learn, but you are missing a shared constructor. ``` shared this(shared C c) { counter++; writeln("this(): ", counter); this.c = c is null ? new shared C() : c; } ```shared static this() { writeln("shared static this(1): ", counter); static if (sharedit) s = cast(shared)S(null); else s = S(null); writeln("shared static this(2): ", counter); }The `sharedit` path constructs a non-shared object, which you cast to a shared one. This causes a copy to occur, so what you're seeing is the destruction of the temporary. Instead, construct a shared object. ``` static if (sharedit) s = shared(S)(null); else s = S(null); ```
Jun 02 2021