「array」 の返す値は、配列の先頭要素のアドレスを返している。型は、char[2][3]
「&*array」 の返す値は、配列の先頭要素のアドレスを返している。型は、char(*)[3]
※型は typeid(array).name()、 typeid(&*array).name で確認。
JIS X3010 6.5.3.2 原文
- [制約]
単項&演算子のオペランドは、関数指示子、[]演算子若しくは単項*演算子の結果、又は左辺値でなければならない。
左辺値の場合、ビットフィールドでもなく、register記憶域クラス指定子付きで宣言されてもいないオブジェクトを指し示さなければならない。
[意味規則]
(1)単項&演算子は、そのオペランドのアドレスを返す。
(2)オペランドが型"〜型"をもっている場合、結果は、型"〜型へのポインタ"をもつ。
(3)オペランドが、単項*演算子の結果の場合、*演算子も&演算子も評価せず、両演算子とも取り除いた場合と同じ結果になる。ただし、その場合でも演算子に対する制約を適用し、結果は左辺値とならない。
同様に、オペランドが[]演算子の結果の場合、単項&演算子と、[]演算子が暗黙に意味する単項*演算子は評価されず、&演算子を削除し[]演算子を+演算子に変更した場合と同じ結果になる。
(5)これら以外の場合、結果はそのオペランドが指し示すオブジェクト又は関数へのポインタとなる。
「え?型変わってるから同じ結果じゃないじゃん。」と思いました。
なぜ型が変わるのでしょうか?
私は、
- (1)「&*array」は「*array」を評価し次に「array of char(要素型はchar)」に対して&演算子を評価しているから「配列(char[3])へのポインタ」を返し、そして型はchar(*)[3]となる。と一見読めるが、これでは両演算子を評価をしてしまっているので定義(3)に反している。
(2)では、最初から考えて、まず演算子の優先順位から「*array」は評価されていると思う。
(3)次に&演算子を評価するときに対象は何かなぁ〜?あっ「*array」は*演算子の結果じゃん。
じゃぁ(返す値の)結果は両演算子とも取り除いた場合と同じ(返す値の)結果になるよ。
(4)けど定義(2)「オペランドが型"〜型"をもっている場合、結果は、型"〜型へのポインタ"をもつ。」だから
「*array」を評価した型は、配列型(array of char(要素型はchar))だから、(型の)結果は「配列型へのポイント」になるよ。
(5)結論
返す値は、両演算子を取り除いた「array」と同じ「配列の先頭要素のアドレスを返している。」
型は、char(*)[3]
ご教示お願い致します。