ちょっと昨日読んだ本の中に,「『α || β』と書いたとき,αとβのどちらが先に評価されるbe evaluatedか分からない」と書かれていて,そんなはずはない,αが先のはず,と本に向かって反発してしまいました.
今朝思い出して,検証プログラムを書いてみました.
#include <stdio.h> int A(void) { printf("A\n"); return 1; } int B(void) { printf("B\n"); return 1; } int C(void) { printf("C\n"); return 0; } int main(void) { return A() || B() && C(); }
これで,
- 「||の前がまず評価され,それが真なら,後ろは評価されない」を優先するのであれば,プログラムは「A」のみを出力する.
- 「&&の優先順位は,||よりも高い」を優先するのであれば,プログラムは「B」「C」「A」を出力する.
なのですが,実行してみたところ,「A」のみでした.
考えてみると,「&&は||よりも優先する」のは,式の“評価方法”に関するもの,すなわちコンパイラ内部でどのように構文木を作るかに関することで,その構文木をどこから評価していくか,つまり式の“評価順序”に関するものではないということになりそうです.
ともあれ今回実行のコンパイラはGCCのみでして,他のコンパイラでも同じ挙動をするかまでは保証できません.そもそもこの問題は,きちんと規格を確認すれば分かるかも.当たることにします….
(補足) GCCで-Wallオプションをつけてコンパイルすると,"warning: suggest parentheses around && within ||"という警告が出ました.「return A() || (B() && C());」と書くべし,ということですね.