読者です 読者をやめる 読者になる 読者になる

括弧が演算子かどうか

C++

id:otn さんに指摘をもらったので調べてみた。
結論:やっぱり優先順位変更のための括弧は演算子ではない。


まず、ISO/IEC 14882:2003 の注釈の 53 に

The precedence of operators is not directly specified, but it can be derived from the syntax.

とあるので、expression まわりを抜粋して並び替えてみると、

expression:
           assignment-expression
           expression , assignment-expression

assignment-expression:
           conditional-expression
           logical-or-expression assignment-operator assignment-expression
           throw-expression

logical-or-expression:
           logical-and-expression
           logical-or-expression || logical-and-expression

logical-and-expression:
           inclusive-or-expression
           logical-and-expression && inclusive-or-expression

inclusive-or-expression:
           exclusive-or-expression
           inclusive-or-expression | exclusive-or-expression

exclusive-or-expression:
           and-expression
           exclusive-or-expression ^ and-expression

and-expression:
           equality-expression
           and-expression & equality-expression

equality-expression:
           relational-expression
           equality-expression == relational-expression
           equality-expression != relational-expression

relational-expression:
           shift-expression
           relational-expression < shift-expression
           relational-expression > shift-expression
           relational-expression <= shift-expression
           relational-expression >= shift-expression

shift-expression:
           additive-expression
           shift-expression << additive-expression
           shift-expression >> additive-expression

additive-expression:
           multiplicative-expression
           additive-expression + multiplicative-expression
           additive-expression - multiplicative-expression

multiplicative-expression:
           pm-expression
           multiplicative-expression * pm-expression
           multiplicative-expression / pm-expression
           multiplicative-expression % pm-expression

pm-expression:
           cast-expression
           pm-expression .* cast-expression
           pm-expression ->* cast-expression

cast-expression:
           unary-expression
           ( type-id ) cast-expression

unary-expression:
           postfix-expression
           ++ cast-expression
           -- cast-expression
           unary-operator cast-expression
           sizeof unary-expression
           sizeof ( type-id )
           new-expression
           delete-expression

postfix-expression:
           primary-expression
           postfix-expression [ expression ]
           postfix-expression ( expression-listopt )
           simple-type-specifier ( expression-listopt )
           typename ::opt nexted-name-specifier identifier ( expression-listopt )
           typename ::opt nexted-name-specifier templateopt template-id ( expression-listopt )
           postfix-expression . templateopt id-expression
           postfix-expression -> templateopt id-expression
           postfix-expression . pseudo-destructor-name
           postfix-expression -> pseudo-destructor-name
           postfix-expression ++
           postfix-expression --
           dynamic_cast < type-id > ( expression )
           static_cast < type-id > ( expression )
           reinterpret_cast < type-id > ( expression )
           const_cast < type-id > ( expression )
           typeid ( expression )
           typeid ( type-id )

primary-expression:
           literal
           this
           ( expression )
           id-expression

こう。primary-expression として、括弧で expression を囲うことが出来る。で、id:otn さんの言うとおり、unary-expression や unary-operator にはそれっぽい部分はなさそうなので、演算子じゃないんだろう。


さらに、C言語ポインタ完全制覇 (標準プログラマーズライブラリ)によると、

優先順位が「最強」である () について,

() は, プログラマーが, 文法で規定された優先順位を無視して強制的に優先順位を設定するときに使用するためのものだ. だから, これの優先順位が最強なのは当然だ.

と考えている人は意外に多いようですが, それは誤解です.
だいたい, この () がそのような意味であるなら, わざわざ優先順位表に載せる必要はないでしょう.
この表の () は, (K&R にも書いてあるように) 関数呼び出しを意味する演算子であり, この場合の優先順位とは, func(a, b) のような式において, func と (a, b) の間の結びつきの強さを意味しています.

C 言語ポインタ完全制覇 (P.176-177)

とあるので、やっぱり優先順位を変更する () は演算子ではない模様*1

*1:K&R は持ってないんです!