也许我遗漏了一些相当简单的东西,但是当我取消引用指针时,即使我检查了表达式开头的点,我也会崩溃。
if( var1 &&
bool1 || bool2 &&
var1->DoSomething() )
{
}
var1 是一个空指针,但 Var1->Dosomething() 仍在被调用。我的理解是 && 和 || C++ 中的运算符是短路的,所以如果 var1 为空,那么它将在一开始就终止。还是我还缺少其他东西?
也许我遗漏了一些相当简单的东西,但是当我取消引用指针时,即使我检查了表达式开头的点,我也会崩溃。
if( var1 &&
bool1 || bool2 &&
var1->DoSomething() )
{
}
var1 是一个空指针,但 Var1->Dosomething() 仍在被调用。我的理解是 && 和 || C++ 中的运算符是短路的,所以如果 var1 为空,那么它将在一开始就终止。还是我还缺少其他东西?
运算符优先级是这里的关键。因为&&
优先级高于||
,所以您的表达式相当于
(var1 && bool1) || (bool2 && var1->DoSomething() )
因此,由于var1
评估为假,bool1
因此未评估并(var1 && bool1)
产生错误,因此 (bool2 && var1->DoSomething())
必须进行评估。如果bool2
碰巧为真,那么var1->DoSomething()
也将被评估,导致未定义的行为。
只需添加一些括号(对于您需要的特定表达式树)就可以了。
由于&&
优先级高于||
,因此您的表达式被解析为(var1 && bool1) || (bool2 && var1->DoSomething())
。现在因为var1
是一个空指针,短路评估意味着bool1
不评估,左侧||
评估为假。因此,要找出表达式的值,必须对右侧进行求值(即此处不进行短路求值!)。||
is的右侧bool2 && var1->DoSomething()
,因此如果bool2
为真,var1->DoSomething()
将被评估。另请注意,即使对于var1
非空值,e 表达式的结果也不总是您可能期望的那样。
简单的。&& 具有更高的优先级,因此您的表达式为:
if( ( var1 && bool1 ) || ( bool2 && var1->DoSomething()) )
尝试
if( var1 && ( bool1 || bool2 ) && var1->DoSomething() )
否则第一个表达式car1 && bool1
失败,第二个表达式被计算。因为 bool2 显然返回 true,如果 bool2 为 true,则您的指针被取消引用。
在此处查找优先列表:http ://en.cppreference.com/w/cpp/language/operator_precedence或使用谷歌。