warning: ‘&&’ within ‘||’
警告:a||b&&cはa||(b&&c)と同じで(a||b)&&cと違う
[-Wlogical-op-parentheses]
■a||(b&&c)でbが先に評価されるわけではない
#include <stdio.h>
#include <stdbool.h>
int a(bool x){ printf("%s()->",__func__); return x;}
int b(bool x){ printf("%s()->",__func__); return x;}
int c(bool x){ printf("%s()->",__func__); return x;}
int main(void){
if(a(0)||b(1)&&c(0))
puts("0||1&&0=真");
else
puts("0||1&&0=偽");
//a||b&&c の評価はどれが先?
#define LOG(X) (printf("%s:",#X),printf("%s\n",(X)?"真":"偽"))
LOG(a(0)||b(0)&&c(0));
LOG(a(0)||b(0)&&c(1));
LOG(a(0)||b(1)&&c(0));
LOG(a(0)||b(1)&&c(1));
LOG(a(1)||b(0)&&c(0));
LOG(a(1)||b(0)&&c(1));
LOG(a(1)||b(1)&&c(0));
LOG(a(1)||b(1)&&c(1));
}
||と&&では&&のほうが結合力が強いです。
なので
a||b&&ccは
a||(b&&c)と同じです。
結合力が強いからといって
(b&&c)が先に評価されるわけではありません。
論理式は左から右へ順番に評価されます。
つまり、必ずaから評価されます。
評価の途中で結果が出たら
以降の評価はされません。
■実行結果
a()->b()->c()->0||1&&0=偽
a(0)||b(0)&&c(0):a()->b()->偽
a(0)||b(0)&&c(1):a()->b()->偽
a(0)||b(1)&&c(0):a()->b()->c()->偽
a(0)||b(1)&&c(1):a()->b()->c()->真
a(1)||b(0)&&c(0):a()->真
a(1)||b(0)&&c(1):a()->真
a(1)||b(1)&&c(0):a()->真
a(1)||b(1)&&c(1):a()->真
かならずa()から評価を行い、
a(1)が成立すると
b(),c()の評価を行わないのが
わかると思います。