25

は、この1つは私が考えて作ったのですか? 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 ++のようにこの状況を診断するために必要なコンパイラはありますか?それとも未定義の動作ですか?

+0

面白い、ちょうどこの昨日に出会った! – UncleZeiv

+0

ちょうど情報のために:Visual C++ 9.0はそのような警告をも示しています... – cybevnm

+0

[なぜ、本当に、不完全な型の削除は未定義の動作ですか?](http://stackoverflow.com/questions/2517245/why-really-不完全な型の未定義の振る舞い) – fredoverflow

答えて

20

削除されるオブジェクトが 削除の時点で 不完全クラス型を有し、完全なクラスが 非自明なデストラクタまたは 解除されている場合関数は、 は未定義です。

それでは、面倒なことがなければUBだし、そうでなければOKです。 UBにとって警告は必要ではありません。

+2

いいえ、「UB if」ではありません。無条件UBです。例えば、そのクラスが 'operator new'を別のヒープにオーバーロードさせ、' delete'ステートメントが 'operator delete'を間違って呼び出すようにすることができます。 – sharptooth

+6

私はあいまいな部分を取り除いた。私が見る限り、標準では、引用した節で述べたように、不完全な型のオブジェクトを削除することはどの場合でもUBであるとは言いません。なぜそれが無条件にUBだと思いますか? (標準ではこれはどこですか?) – etarion

+1

@etarion:標準では、その動作はそのクラスがどのように宣言されているかによって異なります。つまり、それらの要件を満たすクラスから始めて、 (それは途中で「うまくいく」ことができる)UBの顔。したがって正式にはあなたはきれいですが、あなたのコードに致命的なエラーを植えました。問題の警告は、「不完全なクラスの削除」は非常に悪い考えです。 – sharptooth

3

これは未定義の動作であり、pImplパターンを実装する際の共通の問題点です。私の知る限りでは、コンパイラが発行する必要があるという警告はありません。警告は選択肢です。コンパイラの作者が彼らが役に立つと思ったからです。標準[expr.delete]から

5

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

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

// 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を適用し、それはその後、いくつかのコンパイラは、配列を渡す場合、私は考えます負のサイズの場合、エラーが発生します。

関連する問題