Following code doesn't call destructor:
--------------------------
import std.stdio;
struct A
{
this(int a) {writeln("A.ctor");}
~this() {writeln("A.dtor");}
}
void main()
{
A(1);
}
--------------------------
$ dmd -run main
A.ctor
--------------------------
I suppose that this bug is related to a series of problems about the temporary object.
The outbreak of construction, destruction, postblit are as following table:
postblit | destructor
constructor -> parameter ... x | o
constructor -> return value ... x | x
constructor -> variable ... x | o
constructor -> no operate ... x | x
return value -> parameter ... x | o
return value -> return value ... x | x
return value -> variable ... x | o
return value -> no operate ... x | x
variable -> parameter ... o | o
variable -> return value ... o | o
variable -> variable ... o | o
variable -> no operate ... (error) | (error)
* When a variable leaves from the scope, destructor is called.
* When a variable returns from the function or a variable copies to other variable, postblit is called.
Test code is here: http://ideone.com/7ujuN
Are these behaviors correct? I feel suspicious...
I think these behavior should be determined more strictly.
Comment #1 by zan77137 — 2011-04-01T04:44:14Z
I tested following commit:
https://github.com/D-Programming-Language/dmd/commit/e764b3949ae0f95f8fc4d7d2e9114e29fee12493
with following code:
http://ideone.com/Yqomf
and result is here:
http://ideone.com/qfBnx
CONCLUTION:
Almost!
Its behavior is right except a case to ignore without storing away a temporary object produced in a return value to a variable.
+--------------+--------------+----------+------------+-------------+
| source | distination | postblit | destructor | correctness |
+--------------+--------------+----------+------------+-------------+
| constructor | parameter | x | o | OK |
| constructor | return value | x | x | OK |
| constructor | variable | x | o | OK |
| constructor | no operate | x | o | OK |
| return value | parameter | x | o | OK |
| return value | return value | x | x | OK |
| return value | variable | x | o | OK |
| return value | no operate | x | _x_ | _NG_ |
| variable | parameter | o | o | OK |
| variable | return value | o | o | OK |
| variable | variable | o | o | OK |
| variable | no operate | (error) | (error) | OK |
+--------------+--------------+----------+------------+-------------+
(*) x ... not called / o ... called
Minimized case is here:
-----
import std.stdio;
struct A{
this(int x) {writeln("ctor");}
~this(){writeln("dtor");}
}
A foo() { return A(1); }
void main() {
foo();
}
-----
$ dmd -run main
ctor
-----
Comment #3 by bearophile_hugs — 2011-04-13T16:12:05Z
Code in online paste sites like ideone often gets deleted. So I suggest to avoid their usage in Bugzilla, and to just inline the text or add attaches.
Comment #4 by k.hara.pg — 2011-04-14T01:18:34Z
Created attachment 942
Test code.
Comment #5 by k.hara.pg — 2011-04-14T01:21:22Z
Created attachment 943
Test results by patched dmd.
(In reply to comment #3)
> Code in online paste sites like ideone often gets deleted. So I suggest to
> avoid their usage in Bugzilla, and to just inline the text or add attaches.
Thank you for your advice.
The patch fails to call the destructor with the following code:
import std.c.stdio;
struct S
{
int x = 1;
int bar() { return x; }
this(int i)
{
printf("ctor %p(%d)\n", &this, i);
t ~= "a";
}
this(this)
{
printf("postblit %p\n", &this);
t ~= "b";
}
~this()
{
printf("dtor %p\n", &this);
t ~= "c";
}
static string t;
}
S bar() { return S(1); }
void main()
{
bar().x += 1;
}
I'll see if I can come up with a solution.