c ++ 0xでnullptrを削除しても安全ですか?


84

c++03、nullポインタを削除しても効果がないことは明らかです。確かに、それはその中で明確に述べられ§5.3.5/2ています:

どちらの方法でも、deleteのオペランドの値がnullポインターの場合、操作は効果がありません。

ただし、この文の現在のドラフトでc++0x欠落しているようです。ドラフトの残りの部分では、delete-expressionのオペランドがnullポインター定数でない場合に何が起こるかを示す文しか見つかりませんでした。ヌルポインタの削除はまだで定義されてc++0xいますか?もしそうなら、どこで?

ノート:

それがまだ十分に定義されていることを示唆する重要な状況証拠があります。

まず、次のように§5.3.5/2述べている2つの文があります

最初の選択肢(オブジェクトの削除)では、deleteのオペランドの値はnullポインター値である可能性があります...

そして

2番目の選択肢(配列の削除)では、deleteのオペランドの値はnullポインター値または...

これらは、オペランドがnullであることが許可されていることを示していますが、それ自体では、nullの場合に何が起こるかを実際には定義していません。

第二に、の意味を変更することdelete 0は大きな重大な変更であり、標準化委員会がこの特定の変更を行う可能性はほとんどありません。さらに、これがc++0xドラフトの互換性アネックス(アネックスC)の重大な変更であるという言及はありません。ただし、附属書Cは有益なセクションであるため、これには規格の解釈は含まれていません。

一方、nullポインタを削除しても効果がないという事実は、追加の実行時チェックを意味します。多くのコードでは、オペランドがnullになることはないため、このランタイムチェックはオーバーヘッドゼロの原則と矛盾します。たぶん、委員会は、標準のc ++を言語の指定された設計目標にさらに一致させるために、動作を変更することを決定しました。

回答:


101

5.3.5 / 7のコメント:

delete-expressionのオペランドの値がnullポインター値でない場合、delete-expressionは割り当て解除関数(3.7.4.2)を呼び出します。それ以外の場合は、割り当て解除関数が呼び出されるかどうかは指定されていません。

そして3.7.4.2/3は言う:

割り当て解除関数に提供される最初の引数の値は、ヌルポインター値である可能性があります。その場合、および割り当て解除関数が標準ライブラリで提供されている関数である場合、呼び出しは効果がありません。

したがって、標準の割り当て解除関数が使用されているか、ユーザー提供の割り当て解除関数がnullポインターを正しく処理する限り、動作は明確に定義されています。


9
C ++ 14以降、「式がnullポインター値と評価された場合、デストラクタは呼び出されず、割り当て解除関数は呼び出されません。」
ワーマー2017

2
@Wormerそのページは正しくないと思います。C ++ 14標準では、ポインタがnull(5.3.5 / 7)の場合でも、「割り当て解除関数が呼び出されるかどうかは指定されていません」と記載されています。
インタージェイ2017

1
余談ですが、nullファイルポインタに対してfclose()を呼び出すの安全ではありません。Ubuntu(およびおそらく他のオペレーティングシステム)では、fclose(NULL)によりセグメンテーション違反が発生します。
Gerry Beauregard 2018年

7

一方、nullポインタを削除しても効果がないという事実は、追加の実行時チェックを意味します。

新しい文言は、nullポインタの実行時チェックを削除しません。逆に言えば、ドラフト標準は、実装が準拠するためにnullポインタテストを行わなければならないということをさらに近づけています。

また注目に値する:古い標準は、「deleteのオペランドの値がnullポインターの場合、操作は効果がない」と(5.3.5 / 2)と言っていたが、後で(5.3.5 / 7)と言ったという点で矛盾していました。 「delete-expressionは割り当て解除関数を呼び出します。」関数の呼び出しは効果です。呼び出される関数がオーバーライドされる可能性があるため、これは特にそうoperator deleteです。

新しい文言はその矛盾を取り除き、nullポインターを削除する場合に割り当て解除関数が呼び出されるかどうかを実装に明示的に任せます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.