質問

これは私に考えさせました:

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パターンを実装する際の一般的なゴッチャです。私の知る限り、コンパイラが放射する必要があるという警告のようなものはありません。警告は選択的です。コンパイラーライターは、彼らが役に立つと思ったので、彼らはそこにいます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top