17. いくつかの概念(3)
? Safely-derived pointer (value)
これは safely-derived pointer value
T *p = new T;
intptr_t x = reinterpret_cast<intptr_t>(p) ^ 0x555
a:
T *q = reinterpret_cast<T*>(x ^ 0x555);
T y = *q;
こっちは safely-derived pointer value ではない
これも safely-derived pointer value ではない!
※値としては p と同じだが、結果ではなくて過程で判断
20. Strict pointer safety
? Safely-derived pointer (value)
これは safely-derived pointer value
T *p = new T;
intptr_t x = reinterpret_cast<intptr_t>(p) ^ 0x555
a:
T *q = reinterpret_cast<T*>(x ^ 0x555);
T y = *q;
こっちは safely-derived pointer value ではない
これも safely-derived pointer value ではない!
未定義動作
※値としては p と同じだが、結果ではなくて過程で判断
23. (耻苍)诲别肠濒补谤别冲谤别补肠丑补产濒别()の使い方
? どうして必要なの? これは safely-derived pointer value
T *p = new T;
intptr_t x = reinterpret_cast<intptr_t>(p) ^ 0x555
a:
T *q = reinterpret_cast<T*>(x ^ 0x555);
T y = *q;
こっちは safely-derived pointer value ではない
未定義動作 これも safely-derived pointer value ではない!
※値としては p と同じだが、結果ではなくて過程で判断
「ラベル a: の位置で GC がかかると p の参照先が回収される」 ???
24. (耻苍)诲别肠濒补谤别冲谤别补肠丑补产濒别()の使い方
? どうして必要なの? これは safely-derived pointer value
T *p = new T;
intptr_t x = reinterpret_cast<intptr_t>(p) ^ 0x555
a:
T *q = reinterpret_cast<T*>(x ^ 0x555);
T y = *q;
こっちは safely-derived pointer value ではない
未定義動作 これも safely-derived pointer value ではない!
※値としては p と同じだが、結果ではなくて過程で判断
「ラベル a: の位置で GC がかかると p の参照先が回収される」 問題は最適化
25. (耻苍)诲别肠濒补谤别冲谤别补肠丑补产濒别()の使い方
? どうして必要なの?
T *p = new T; 以降 p の値は
intptr_t x = reinterpret_cast<intptr_t>(p) ^ 0x555 使われない
a:
T *q = reinterpret_cast<T*>(x ^ 0x555);
T y = *q;
※ p, x, q を同じレジスタに割り当てることが可能 以降 x の値は
→ラベル a: の時点で p の値がどこにも存在しない 使われない
→p の参照先 = q の参照先が GC の回収対象になる!!
→*q で未定義動作
「ラベル a: の位置で GC がかかると p の参照先が回収される」 問題は最適化
26. (耻苍)诲别肠濒补谤别冲谤别补肠丑补产濒别()の使い方
? C++0xでの正しいコード
*p は
reachable T *p = new T;
= declare_reachable(p); // 偽装前に declare_reachable() を呼ぶ
GC対象外 intptr_t x = reinterpret_cast<intptr_t>(p) ^ 0x555
a:
// T z = *reinterpret_cast<T*>(x ^ 0x555); // 合法
// 偽装終了時に undeclare_reachable() を呼ぶ
T *q = undeclare_reachable(reinterpret_cast<T*>(x ^ 0x555));
T y = *q;
注
※ declare_reachable した値と同じであれば safely-derived でなくとも逆参照が可能
※ undeclare_reachable の引数は safely-derived でなくとも reachable であれば良い
※ declare_reachable については「ポインタ値を偽装する」点が問題
a: で関数が別れている場合を考えれば最適化なしで議論は一緒
28. 参考文献
? N2670: Minimal Support for Garbage
Collection and Reachability-Based Leak
Detection (revised)
http://www.open-
std.org/jtc1/sc22/wg21/docs/papers/2008/
n2670.htm
? Garbage Collection in the Next C++
Standard
http://www.hpl.hp.com/techreports/2009/H
PL-2009-360.pdf