也许我错过了一些相当简单的事情,但即使我在表达式的开头检查了一个指针,但是我得到了一个崩溃。C++短路评估
if(var1 &&
bool1 || bool2 &&
var1->DoSomething())
{
}
var1是一个空指针,但是Var1-> Dosomething()仍然被调用。我的理解是,& &和|| C++中的运算符是短路的,所以如果var1为空,那么它只会在最开始时结束。还是有什么我失踪?
也许我错过了一些相当简单的事情,但即使我在表达式的开头检查了一个指针,但是我得到了一个崩溃。C++短路评估
if(var1 &&
bool1 || bool2 &&
var1->DoSomething())
{
}
var1是一个空指针,但是Var1-> Dosomething()仍然被调用。我的理解是,& &和|| C++中的运算符是短路的,所以如果var1为空,那么它只会在最开始时结束。还是有什么我失踪?
Operator precedence是这里的关键。由于&&
比||
更高的优先级,你的表情是相当于
(var1 && bool1) || (bool2 && var1->DoSomething())
所以,既然var1
计算结果为false,bool1
不评估和(var1 && bool1)
产生虚假的,因此(bool2 && var1->DoSomething())
必须进行评估。如果bool2
碰巧是真的,那么var1->DoSomething()
也将被评估,导致未定义的行为。
只需添加一些括号(对于您需要的特定表达式树),您就会好起来的。
简单。 & &具有更高的优先级,以便您的表情写着:
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或使用谷歌。
由于&&
的优先级高于||
,因此将您的表达式解析为(var1 && bool1) || (bool2 && var1->DoSomething())
。现在因为var1
是空指针,所以短路评估意味着bool1
未被评估,并且||
的左侧评估为假。因此,为了找出表达式的值,必须评估右侧(即短路评估确实是而不是)。 ||
的右侧是bool2 && var1->DoSomething()
,因此如果bool2
为真,则将评估var1->DoSomething()
。另请注意,即使var1
非null,eexpression的结果也不会总是您期望的结果。
如有疑问,**加括号**! – 2012-01-14 16:12:16