1. ホーム
  2. c++

[解決済み] c++0xでnullptrを削除しても大丈夫でしょうか?

2022-01-31 20:03:59

質問内容

c++03 は、NULLポインタを削除しても何の効果もないことを明確に示しています。実際、以下のように明示的に記述されています。 §5.3.5/2 ということです。

いずれの方法でも、deleteのオペランドの値がヌルポインタの場合、その操作は何の効果もない。

しかし、現在の ドラフト に対して c++0x という文が抜けているようです。他の草案では、オペランドが 削除式 はヌルポインタ定数ではありません。ヌルポインタの削除はまだ c++0x また、そうであれば、どこで?

注意事項

今でも十分な定義があることを示唆する重要な状況証拠がある。

まず §5.3.5/2 と記述しています。

最初の選択肢(deleteオブジェクト)では、deleteのオペランドの値がNullポインタの値である可能性がある、......。

そして

2つ目の選択肢(配列の削除)では、削除のオペランドの値がヌルポインタの値であるか、または ...

これらは、オペランドがNULLであることを許容することを述べていますが、それ自体では、NULLの場合に何が起こるかを実際に定義しているわけではありません。

次に delete 0 は、大きな破壊的変更であり、標準化委員会がこの特別な変更を行う可能性は非常に低いでしょう。さらに、この変更がブレークスルーであることは c++0x 草案 しかし、Annex CはInformativeセクションであり、規格の解釈とは関係ありません。

一方、NULLポインタを削除しても効果がないことを要求していることは、実行時のチェックを追加していることを意味します。多くのコードではオペランドがNULLになることはありえないので、この実行時チェックはゼロオーバーヘッドの原則と相反するものです。おそらく委員会は、標準c++を言語の設計目標に沿ったものにするために、この動作を変更することを決定したのでしょう。

解決方法は?

5.3.5/7に書いてあります。

<ブロッククオート

delete-expressionのオペランドの値がヌルポインタ値でない場合、deallocation関数が呼び出されます(3.7.4.2)。それ以外の場合は、デアロケーション関数が呼び出されるかどうかは不特定です。

と3.7.4.2/3には書いてあります。

もしそうなら、そしてもし再配置関数が標準ライブラリで提供されているものなら、その呼び出しは何の効果も持ちません。

つまり、標準の割り当て解除関数を使うか、ユーザーが提供する割り当て解除関数でヌルポインターを正しく処理する限り、動作はきちんと定義されているのです。