2012-01-14 110 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的結果也不會總是您期望的結果。