uint ci = 0;
struct S
{
uint i;
this(int x)
{
i = ci;
ci++;
writeln("new: ", i);
}
this(this)
{
i = ci;
ci++;
writeln("copy ", i);
}
~this()
{
writeln("del ", i);
}
S save1() // produces 2 copies in total
{
S s = this;
return s;
}
auto save2() // produces 3 copies in total
{
S s = this;
return s;
}
}
Save1:
S s = S(1);
S t = S(1);
t = s.save1();
// Gives:
// new 0
// new 1
// copy 2
// del 1
// del 2
// del 0
Save2:
S s = S(1);
S t = S(1);
t = s.save2();
// Gives:
// new 0
// new 1
// copy 2
// copy 3
// del 3
// del 1
// del 3
// del 0
As you can see, the save2() variant never ‘deletes’ the struct with i == 2. Is it memory leaking? I cannot properly manage my resources in structs if I use auto as return type.
Also, if save() simply return this without the temporary, I get:
S save()
{
return this;
}
// new 0
// new 1
// copy 2
// del 1
// del 2
// del 2
Are these bugs? How am I supposed to do proper memory management if I cannot define a default constructor? What is the reason behind this design decision?
I want to use it for a forward range, so I cannot use class.
Looks like a bug to me. Apparently the only difference between
save1andsave2is that the latter usesautoreturn instead of an explicit return type. Except in a few corner cases that don’t apply here, this should have no effect on postblit and d’tor calls.