鍋あり谷あり

テーマを決めずに適当に書いています。

三項演算子の優先順位

C/C++Java などの本を見ると、必ず演算子の優先順位が書いてある。
演算子の優先順位は、どれもだいたい
コンマ演算子 < 代入演算子 < ?:演算子 < それ以外全部
となっている。
が。
実際は優先順位が逆転するケースがある。
C++で

a+=1 ? b+=2 : c+=4;
d, e ? f, g : h, i;

と書くと、代入演算子コンマ演算子が式を分断するので

a+=( 1 ? b )+=( 2 : c )+=4;
d,( e ? f ) ,( g : h ), i;

となり、コンパイルエラーになりそうなものだと思っていたが、そうはならず、
こう

a+= ( 1 ? ( b+=2 ) : ( c+=4 ) );
d, ( e ? ( f, g ) : h ), i;

なる。
なんといっても気持ち悪いのは、コンマと代入で括弧のつけ方が違うところ。
で。
ほかの言語はどうだろうと思って調べてみた。

ruby

a, b ? c, d : e, f # syntax error
a=b ? c=d : e=f; # a=(b ? (c=d) : (e=f));

ruby の場合、コンマが演算子かどうかよくわからないという問題がある。
代入については、C, C++ と同じ。

javascript

1, 2 ? 3, 4 : 5, 6; // syntax error
a=1 ? b=1 : c=2; // a=(1 ? (b=1) : (c=2))

javascriptruby と同じ挙動。
ruby とちがって、コンマは演算子じゃないかもしれないという不安はない。

perl5, PHP

1, 2 ? 3, 4 : 5, 6; # syntax error
$a+=1 ? $b+=2 : $c+=4; # $a+=((1 ? ($b+=2) : $c)+=4);

C, C++, ruby, javascript とは括弧のつけ方が違う。
PHPperlと同じだった。歴史を感じる。

groovy

a+=1 ? b+=2 : c+=4;//a+=((1 ? (b+=2) : c)+=4); 
// bad expression as the left hand side of an assignment operator

a,1 ? b,2 : c,4; // エラー unexpected token

代入の方については、groovy は perl と同じ括弧の付け方をするものの、左辺値になる式の条件が perl とは違うようで、エラーになる。
コンマの方はエラー。なにがどうエラーなのかはよくわからない。コンマ演算子ないのかも。

perl6

1, 2 ? 3, 4 : 5, 6; # confused
$a+=1 ?? $b+=2 !! $c+=4; # confused

perl6 は perl とも異なり、syntax error という趣旨だと思われる confused となった。
上記の通り、perl6 の三項演算子は ?: ではなく、?? !! になったらしい。
!! は ! 二個にも見えるので、混乱が生じそうな気もするがどうなんだろう。


C#javaとDが残っているけど、どうせ C/C++ と同じだろうと思う。どうだろう。
まあとにかく。各言語で結構挙動が違っていて面白いという話。
あとなんかあったっけ。