構造体のポインタで,間接参照演算子「*」を使ったメンバ変数の参照手順を以下に示しておこう.
(*record).name()と「.」の優先順位は同じだが,この場合,評価順が左から右となり,(*record)が先に評価される.評価結果に対して「.」を評価するため,コンパイラは正しくnameメンバ変数を参照できる,という仕組みだ.
(ここが変だよC言語 下, pp.4-5)
『()と「.」の優先順位は同じだが』が間違いで,構文規則に基づいて考えると,()の優先順位は,「.」よりも高いです.
構文規則を,JIS X 3010 : 2003*1の6.5.1節と6.5.2節から抜き出してみました.
- 「一次式」は,以下のいずれかである.
- 識別子
- 定数
- 文字列リテラル
- ( 式 ) ...ここ!!
- 「後置式」は,以下のいずれかである.
少なくとも,() と「.」のカテゴリが違うなあということが分かります.あとはこの種の構文規則の読み方を知っていれば*4,() の優先順位は,「.」よりも高いと結論付けられます.
ところで,上記の後置式の定義の中に,後置の増分・減分演算子が書かれています.「ということは前置と後置で,優先順位が違ってくるのか?」という疑問も生じるのですが,上巻の中に,これに関連しそうな気になる記述がありますので,後日,報告することにします.
「*record.name」と記述した場合,演算子の優先順位の規則から「*」より「.」が優先される.従って,まずrecord.nameを評価し,その結果に対して「*」が評価される.(略) ゆえに,「*record.name」はコンパイルエラーになる.
(前掲書, p.4)
それぞれの文は間違いでないのですが,違和感があります.
その理由を考えてみると,「演算子の優先順位は,式の評価方法how an expression is constructedを定めるものであり,式の評価順序を定めるものではない」のでした.
そういえばかつて日記に書いたぞ…これだ: ANDよりもORが優先することがある - わさっき