演算子の優先度と副作用について

C言語はかなり長い間お付き合いをしているが,演算子の優先度と副作用あたらりがどうやら怪しいらしい.
ポインタ並に難しいのではないかと思う,今日この頃です.
とりあえず,簡単に自分的まとめ


演算子の優先度

演算子 結合規則
() [] -> . ++ --(後置) 左から右
! ~ ++ --(前置) + -(符号) * &(アドレス) (type) sizeof 右から左
* / % 左から右
+ - 左から右
<< >> 左から右
< <= > >= 左から右
== != 左から右
& 左から右
^ 左から右
左から右
&& 左から右
|| 左から右
? : 右から左
= += -= *= /= %= &= ^= |= <<= >>= 右から左
, 左から右

この表は覚えておいて損はないのですが・・・一つ疑問.

後置演算子が優先度高いってどういうことなんだ?

int i = 0,sum;
sum = i++;

とかあった場合,どの段階でiの値が増加するかと言うと,;が来る前までに増加します.
つまり,sumには増加するまえのiの値が入り,その後にiが1増えるという.
・・・なんか表を見てると納得いかない.

ちなみに前置演算子の場合は

int i=0, sum;
sum = ++i;

だと,iの値が増加してからsumに代入されます.
これは,納得なんですよね.
だって,前置演算子の方が表を見る限りでは優先度が高いですからね.


これはどうなるのでしょうか?

int i = 0, a[3];
a[i] = i++;

私の環境では,a[0]にiの値が入ってから,iが1増加しました.
ちなみに,コンパイラによって動作は変わります.
つまり,iの値が増加してから,a[1]に値が入る場合があるかもしれないということです.
前置・後置演算子副作用を発生させやすいのです.(う〜ん,難しくなってきた)


次の場合のsumの値はどうなるのでしょうか?

int sum, i =0;
sum = ++i * ++i * ++i;

私の環境では,「12」でした.
おそらく,左と真ん中の「++i」が1づつ増えてから掛け合わされて,右の「++i」が1増えてから左と掛け合わされたものかと・・・.(何言ってるのかさっぱりになってきた)
ちなみに,これもコンパイラによって結果が変わります.


今まで演算子の優先順位と副作用についてかるーく説明しましたが,ここで重要なポイント!

優先順位と結合規則によって式の意味はきまります.
しかし,どういう順番で計算されるかは,わかりません!!

なんじゃそりゃ!!!
優先順位と結合規則はあくまで「目安」であって,計算はその値になるように適当にやられてるっぽいです.
(ある意味すごいのかも?)

・・・C言語恐るべし