2012-01-14 125 views
2

也许我错过了一些相当简单的事情,但即使我在表达式的开头检查了一个指针,但是我得到了一个崩溃。C++短路评估

if(var1 && 
    bool1 || bool2 && 
    var1->DoSomething()) 
{ 

} 

var1是一个空指针,但是Var1-> Dosomething()仍然被调用。我的理解是,& &和|| C++中的运算符是短路的,所以如果var1为空,那么它只会在最开始时结束。还是有什么我失踪?

+10

如有疑问,**加括号**! – 2012-01-14 16:12:16

回答

12

Operator precedence是这里的关键。由于&&||更高的优先级,你的表情是相当于

(var1 && bool1) || (bool2 && var1->DoSomething()) 

所以,既然var1计算结果为false,bool1不评估和(var1 && bool1)产生虚假的,因此(bool2 && var1->DoSomething())必须进行评估。如果bool2碰巧是真的,那么var1->DoSomething()也将被评估,导致未定义的行为。

只需添加一些括号(对于您需要的特定表达式树),您就会好起来的。

1

简单。 & &具有更高的优先级,以便您的表情写着:

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或使用谷歌。

2

由于&&的优先级高于||,因此将您的表达式解析为(var1 && bool1) || (bool2 && var1->DoSomething())。现在因为var1是空指针,所以短路评估意味着bool1未被评估,并且||的左侧评估为假。因此,为了找出表达式的值,必须评估右侧(即短路评估确实是而不是)。 ||的右侧是bool2 && var1->DoSomething(),因此如果bool2为真,则将评估var1->DoSomething()。另请注意,即使var1非null,eexpression的结果也不会总是您期望的结果。