Thread overview
Struct bug?
Oct 02, 2017
Andrea Fontana
Oct 02, 2017
Biotronic
Oct 02, 2017
Andrea Fontana
Oct 02, 2017
Biotronic
October 02, 2017
Why this code doesn't write two identical lines?

https://dpaste.dzfl.pl/e99aad315a2a

Andrea
October 02, 2017
On Monday, 2 October 2017 at 08:47:47 UTC, Andrea Fontana wrote:
> Why this code doesn't write two identical lines?
>
> https://dpaste.dzfl.pl/e99aad315a2a
>
> Andrea

A reduced example of where it goes wrong:

class B {}

struct A {
    B b = new B;
}

unittest {
    A a1, a2;
    assert(a1 == a2);
}

In other words, when you initialize the class reference in your struct, it has to be a value that's known at compile-time. So the compiler creates a single instance of B, and every instance of A points to it. So this line:

    A a = A(A(1), 2);

first appends 1 to b.data, then appends 2 to b.data, and it's the same b in both cases.

Not knowing what you're attempting to do, I'm not sure how to fix your problem. But if what I've described above does indeed cover it, initializing b in the constructor is the way to get it to work.

--
  Biotronic
October 02, 2017
On Monday, 2 October 2017 at 09:08:59 UTC, Biotronic wrote:
> Not knowing what you're attempting to do, I'm not sure how to fix your problem. But if what I've described above does indeed cover it, initializing b in the constructor is the way to get it to work.
>
> --
>   Biotronic

Obviusly real example is quite different and larger.
Anyway: you cant put a default destructor on struct
October 02, 2017
On Monday, 2 October 2017 at 09:34:29 UTC, Andrea Fontana wrote:
> Anyway: you cant put a default destructor on struct

True. In which case you should either @disable this() (which presents its own set of issues) or hide b behind a @property function, something like:

struct S {
    B _b;

    @property
    B b() {
        if (_b is null) _b = new B();
        return b;
    }
}

This exact same issue also crops up for classes, since typeid(T).initializer is simply blitted over the newly allocated memory. At least for classes we could change the language such that:

class C {
    int[] p = new int[5];
}

is sugar for:

class C {
    int[] p;
    this() {
        p = new int[5];
    }
}

No such solution exists for structs, since they don't have default constructors.

--
  Biotronic