不完全なタイプのオブジェクトを削除します
-
29-09-2019 - |
質問
これは私に考えさせました:
class X;
void foo(X* p)
{
delete p;
}
どうすればよいでしょうか delete p
私たちが知らないなら X
目に見えるデストラクタはありますか? G ++ 4.5.1は3つの警告を示します。
warning: possible problem detected in invocation of delete operator: warning: 'p' has incomplete type warning: forward declaration of 'struct X'
そして、それは言う:
ノート: クラスが定義されているときに宣言されていても、デストラクタもクラス固有の演算子削除も呼び出されません。
うわー... G ++のようにこの状況を診断するためにコンパイラが必要ですか?それとも未定義の動作ですか?
解決
標準から[expr.delete]から:
削除されているオブジェクトの削除ポイントでクラスタイプが不完全であり、完全なクラスに非自明のデストラクタまたは取引機能がある場合、動作は未定義です。
したがって、そうすることがない場合はUBです。そうでない場合は大丈夫です。 UBの警告は壊死していません。
他のヒント
未定義の動作です。
ただし、Boostのように、コンパイラに不完全なタイプをチェックするようにすることができます。
// verify that types are complete for increased safety
template<class T> inline void checked_delete(T * x)
{
// intentionally complex - simplification causes regressions
typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
(void) sizeof(type_must_be_complete);
delete x;
}
申請中 sizeof
不完全なタイプにエラーがトリガーされるはずであり、コンパイラで渡された場合、負のサイズの配列がエラーをトリガーすると思います。
これは未定義の動作であり、PIMPLパターンを実装する際の一般的なゴッチャです。私の知る限り、コンパイラが放射する必要があるという警告のようなものはありません。警告は選択的です。コンパイラーライターは、彼らが役に立つと思ったので、彼らはそこにいます。
所属していません StackOverflow