回答編集履歴
4
逆参照は間接参照とも…
answer
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
-
いいえ、[ヌルポインタの逆参照](https://ja.cppreference.com/w/cpp/language/ub#.E3.83.8C.E3.83.AB.E3.83.9D.E3.82.A4.E3.83.B3.E3.82.BF.E3.81.AE.E9.80.86.E5.8F.82.E7.85.A7)は未定義動作になるため、該当の部分の前でチェックしておく必要があります。二つの違いは「だれが`nullptr`の場合を担保するのか?」です。
|
1
|
+
いいえ、[ヌルポインタの逆参照(間接参照)](https://ja.cppreference.com/w/cpp/language/ub#.E3.83.8C.E3.83.AB.E3.83.9D.E3.82.A4.E3.83.B3.E3.82.BF.E3.81.AE.E9.80.86.E5.8F.82.E7.85.A7)は未定義動作になるため、該当の部分の前でチェックしておく必要があります。二つの違いは「だれが`nullptr`の場合を担保するのか?」です。
|
2
2
|
|
3
|
+
※ 逆参照"dereference"(間接参照"indirection"とも呼ばれる)と参照渡しにおける左辺値参照"lvalue reference"は全く別の概念であり、混合してはいけません。
|
4
|
+
|
3
5
|
### ポインタの値渡しの場合
|
4
6
|
|
5
7
|
関数側が`nullptr`が来ることを想定しておかなければなりません。`nullptr`が渡された場合どのような動作をするのか、例えば、
|
@@ -17,7 +19,7 @@
|
|
17
19
|
|
18
20
|
関数側は`nullptr`が来ることを想定する必要がありません。必ず何かしらの実体が引数と渡されます。ですので、ポインタの値渡しであったような、`nullptr`であったらの動作を定義する必要も無いですし、チェックする必要もありません。
|
19
21
|
|
20
|
-
さて、呼び出し側はどうかと言うことです。呼び出し側もチェックする必要は無いように思います。しかし、もともとポインタであった物を渡したい場合、逆参照して通常のオブジェクトとして渡す必要があります。質問のコードの`*pRet`の部分ですね。ポインタを逆参照するとき、そのポインタが`nullptr`ではないことを保証するのは、逆参照を書いている側です。つまり、呼び出し側で`*pRet`が安全に使えるかを確認しておく必要があります。結局の所、コード全体ではどこかでチェックは必要になると言うことです。
|
22
|
+
さて、呼び出し側はどうかと言うことです。呼び出し側もチェックする必要は無いように思います。しかし、もともとポインタであった物を渡したい場合、逆参照して通常のオブジェクトとして渡す必要があります。質問のコードの`*pRet`の部分ですね。ポインタを逆参照(間接参照)するとき、そのポインタが`nullptr`ではないことを保証するのは、逆参照(間接参照)を書いている側です。つまり、呼び出し側で`*pRet`が安全に使えるかを確認しておく必要があります。結局の所、コード全体ではどこかでチェックは必要になると言うことです。
|
21
23
|
|
22
24
|
---
|
23
25
|
|
3
文が変だった
answer
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
いいえ、[ヌルポインタの逆参照](https://ja.cppreference.com/w/cpp/language/ub#.E3.83.8C.E3.83.AB.E3.83.9D.E3.82.A4.E3.83.B3.E3.82.BF.E3.81.AE.E9.80.86.E5.8F.82.E7.85.A7)は未定義動作になるため、該当の部分の前でチェックしておく必要
|
1
|
+
いいえ、[ヌルポインタの逆参照](https://ja.cppreference.com/w/cpp/language/ub#.E3.83.8C.E3.83.AB.E3.83.9D.E3.82.A4.E3.83.B3.E3.82.BF.E3.81.AE.E9.80.86.E5.8F.82.E7.85.A7)は未定義動作になるため、該当の部分の前でチェックしておく必要があります。二つの違いは「だれが`nullptr`の場合を担保するのか?」です。
|
2
2
|
|
3
3
|
### ポインタの値渡しの場合
|
4
4
|
|
2
感じにする
answer
CHANGED
@@ -9,7 +9,7 @@
|
|
9
9
|
3. 未定義動作。(C由来の関数のほとんどがそう)
|
10
10
|
4. 例外を発生させる。(C++では処理が重い例外は敬遠されるせいか、あまり見かけないような気がする。Javaではこちらが多い印象(勝手にヌルポになっているというのもあるが))
|
11
11
|
|
12
|
-
等が考えられ、あらかじめ決めておきます。そして、3.の未定義動作を除けば、関数
|
12
|
+
等が考えられ、あらかじめ決めておきます。そして、3.の未定義動作を除けば、関数内で`nullptr`であるかをチェックして、あらかじめ決めておいた動作をする必要があるでしょう。
|
13
13
|
|
14
14
|
対して、呼び出し側は`nullptr`を渡しても、`nullptr`の時の動作をするだけなので、その動作で十分であれば、チェックしておく必要がありません。`if (p != nullptr) free(p);`とかしなくても良いって事です。
|
15
15
|
|
1
誤字の修正
answer
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
### ポインタの値渡しの場合
|
4
4
|
|
5
|
-
関数側が`nullptr`が来ることを想定しておかなければなりません。`nullptr`が渡された場合どのような
|
5
|
+
関数側が`nullptr`が来ることを想定しておかなければなりません。`nullptr`が渡された場合どのような動作をするのか、例えば、
|
6
6
|
|
7
7
|
1. 何もしない。(`free()`がそう)
|
8
8
|
2. 必要なサイズを返す、必要な領域が確保されて返す、など別の動作をする。(Win32APIに多い)
|