sizeof を使用しない配列のサイズの検索では、配列のサイズは次の方法で計算されます。
int arr[100];
printf ("%td", (&arr)[1] - arr);
ここで、ポインター演算の目的で、arr
は単一要素配列の要素と見なされるため、
&arr + 1
は、その (概念的な) 単一要素配列の末尾を 1 つ過ぎたポインターであるため、 のアドレスをarr[0]
減算すると、 の要素数arr
が取得されます。
では(&arr)[1]
、そのポインターは間接演算子のオペランドです。
(&arr)[1] ≡ *(&arr + 1)
結果の配列式は、int*
6.3.2.1 (3) に従ってに変換されます。
ここまでは順調ですね。しかし、6.5.6 (8) (加法演算子) の最後の文、
結果が配列オブジェクトの最後の要素の 1 つ後ろを指している場合、評価される単項演算子のオペランドとして使用されません
*
。
そこでの間接演算子の評価を禁止します。
問題は、間接演算子が評価されるかどうかです。
*(&arr + 1) - arr
(その場合、その式は未定義の動作を呼び出します) または配列からポインターへの変換は評価を消滅させます (この場合はすべて問題あり&(*(&arr + 1))
ません) sizeof
。