Re: 一時構造体のデストラクタが呼ばれない

投稿ツリー


このトピックの投稿一覧へ

なし Re: 一時構造体のデストラクタが呼ばれない

msg# 1.4.2.1
depth:
3
前の投稿 - 次の投稿 | 親投稿 - 子投稿なし | 投稿日時 2011/4/1 20:15
SHOO  管理人   投稿数: 658
検証してみました。

#code(d){{{
import std.stdio, std.string;
int indent;
void disp(ARGS...)(ARGS args){
foreach (i;0..indent) write(" ");
static if (ARGS.length == 1 && is(ARGS[0]==string)) {
writeln(args);
} else {
writefln(args);
}
}
void enterdisp(ARGS...)(ARGS args){
indent++;
disp(args);
}
void exitdisp(ARGS...)(ARGS args){
disp(args);
indent--;
}

int count;
int ctor, cpctor, dtor;
bool[int] map;

struct A {
int data;
this(int a){
data = count++;
assert(data !in map);
map[data] = true;
disp("ctor %d[%08x]", data, cast(void*)&this);
ctor++;
}
this(this){
assert(data in map, format("Error: copy source is already destroyed %d[%08x]", data, cast(void*)&this));
data = count++;
map[data] = true;
disp("cpctor %d[%08x]", data, cast(void*)&this);
cpctor++;
}
~this() {
assert(data in map, format("Error: this instance is already destroyed %d[%08x]", data, cast(void*)&this));
map.remove(data);
disp("dtor %d[%08x]", data, cast(void*)&this);
dtor++;
}
}

A retval() {
enterdisp("enter retval");
scope (exit) exitdisp("exit retval");
return A(1);
}
void argval(A a) {
enterdisp("enter argval");
scope (exit) exitdisp("exit argval");
}
A retargval(A a) {
enterdisp("enter retargval");
scope (exit) exitdisp("exit retargval");
return a;
}
A retretval() {
enterdisp("enter retretval");
scope (exit) exitdisp("exit retretval");
return retval();
}
void main() {

{
argval(A(0)); // ctor[0], (dtor[0])
disp("--1--");
retval(); // (ctor[1])->(dtor[1] doesn't call!!!)
disp("--2--");
auto a = A(0); // ctor[2], a.dtor[2]
disp("--3--");
argval(retval()); // (ctor[3]), (dtor[3])
disp("--4--");
auto b = retval(); // (ctor[4]), b.dtor[4]
disp("--5--");
retargval(A(0)); // ctor[5], (postblit[6])->(dtor[6] doesn't call!!!), (dtor[5])
disp("--6--");
auto c = retretval(); // (ctor[7]), c.dtor[7]
disp("--7--");
auto d = retargval(A(0)); // ctor[8], (postblit[9]), (dtor[8]), d.dtor[9]
disp("--8--");
A(0); // ctor[10], dtor[10]
disp("--9--");
argval(a); // (postblit[11]), (dtor[11])
disp("--10--");
A e = a; // e.postblit[12], e.dtor[12]
}
// 9 / 4 / 11 <- !!!This doesn't get symmetry!!!
writeln("ctor / cpctor / dtor");
writefln("%-4d / %-6d / %-4d", ctor, cpctor, dtor);

assert(map.keys.length == ctor+cpctor-dtor);
assert(ctor+cpctor == dtor, format("Remaining data:%s", map.keys));
}
}}}

#code(console){{{
$ dmd -run main
ctor 0[0018fe14]
enter argval
exit argval
dtor 0[0018fde8]
--1--
enter retval
ctor 1[0018fde4]
exit retval
--2--
ctor 2[0018fe1c]
--3--
enter retval
ctor 3[0018fde4]
exit retval
enter argval
exit argval
dtor 3[0018fde8]
--4--
enter retval
ctor 4[0018fde4]
exit retval
--5--
ctor 5[0018fe28]
enter retargval
cpctor 6[0018fe2c]
exit retargval
dtor 5[0018fe04]
--6--
enter retretval
enter retval
ctor 7[0018fdb4]
exit retval
exit retretval
--7--
ctor 8[0018fe38]
enter retargval
cpctor 9[0018fe34]
exit retargval
dtor 8[0018fe04]
--8--
ctor 10[0018fe3c]
dtor 10[0018fe3c]
--9--
cpctor 11[0018fe40]
enter argval
exit argval
dtor 11[0018fde8]
--10--
cpctor 12[0018fe44]
dtor 12[0018fe44]
dtor 9[0018fe34]
dtor 7[0018fe30]
dtor 4[0018fe24]
dtor 2[0018fe1c]
ctor / cpctor / dtor
9 / 4 / 11
core.exception.AssertError@main.d(97): Remaining data:[1,6]
}}}


| オブジェクト源 | 格納先 | postblit | destructor | 正しいか? |h
| constructor | parameter | x | o | o |
| constructor | return value | x | x | o |
| constructor | variable | x | o | o |
| constructor | no operate | x | o | o |
| return value | parameter | x | o | o |
| return value | return value | x | x | o |
| return value | variable | x | o | o |
| return value | no operate | x | &COLOR(red){x}; | &COLOR(red){x}; |
| variable | parameter | o | o | o |
| variable | return value | o | o | o |
| variable | variable | o | o | o |
| variable | no operate | (error) | (error) | o |


おしい!
現段階でデストラクタが正常に呼ばれないパターンは、関数の戻り値(テンポラリオブジェクト)を変数で受けずに無視する場合です。
投票数:17 平均点:4.71
返信する

この投稿に返信する

題名
ゲスト名
投稿本文

  条件検索へ


メインメニュー

ログイン

ユーザー名:


パスワード:





パスワード紛失  |新規登録

Menu