28

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

class X;

void foo(X* p)
{
    delete p;
}

デストラクタが表示されdelete pているかどうかさえわからない場合、どうすればよいでしょうか。Xg++ 4.5.1 では、次の 3 つの警告が表示されます。

warning: possible problem detected in invocation of delete operator:
warning: 'p' has incomplete type
warning: forward declaration of 'struct X'

そして、それは言います:

注:クラスの定義時に宣言されていても、デストラクタもクラス固有の演算子 delete も呼び出されません。

うわー... g ++のように、この状況を診断するためにコンパイラが必要ですか? それとも未定義の動作ですか?

4

3 に答える 3

22

標準[expr.delete]から:

削除されるオブジェクトが削除の時点で不完全なクラス型を持ち、完全なクラスに重要なデストラクタまたは割り当て解除関数がある場合、動作は未定義です。

つまり、重要な作業があれば UB であり、そうでない場合でも問題ありません。UB では警告は必要ありません。

于 2010-12-01T14:13:42.577 に答える
7

これは未定義の動作です。

ただし、ブーストなどの不完全な型をコンパイラにチェックさせることができます。

// 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するとエラーが発生するはずです。それがコンパイラで成功した場合、負のサイズの配列はエラーを引き起こすと思います。

于 2010-12-01T15:25:15.853 に答える
4

これは未定義の動作であり、pImpl パターンを実装する際によくある落とし穴です。私の知る限り、コンパイラが発行する必要があるという警告などはありません。警告は選択的です。それらが存在するのは、コンパイラの作成者がそれらが役立つと考えたからです。

于 2010-12-01T14:12:02.197 に答える