Reputation: 41
Maybe I am missing something rather simple, but I am getting a crash when I dereference a pointer even though I check the point at the very beginning of the expression.
if( var1 &&
bool1 || bool2 &&
var1->DoSomething() )
{
}
var1 is a null pointer, but Var1->Dosomething() is still being called. My understanding is that the && and the || operator in C++ are short circuit so if var1 was null then it would just terminate at the very beginning. Or is there something else I am missing?
Upvotes: 3
Views: 615
Reputation: 19721
Since &&
has higher precedence than ||
, your expression is parsed as (var1 && bool1) || (bool2 && var1->DoSomething())
. Now since var1
is a null pointer, short circuit evaluation means that bool1
is not evaluated, and the left hand side of ||
evaluates as false. Thus to find out the value of the expression, the right hand side has to be evaluated (i.e. short-circuit evaluation does not kick in here!). The right hand side of ||
is bool2 && var1->DoSomething()
, thus if bool2
is true, var1->DoSomething()
will be evaluated. Note also that even for var1
non-null, the result of the eexpression will not always be what you probably expected.
Upvotes: 2
Reputation: 4975
Simple. && has higher precedence so your expression reads:
if( ( var1 && bool1 ) || ( bool2 && var1->DoSomething()) )
try
if( var1 && ( bool1 || bool2 ) && var1->DoSomething() )
otherwise the first expression car1 && bool1
fails and the second expression is evaluated. since bool2 returns true apparently your pointer is dereferenced if bool2 is true.
look here for a precedencelist: http://en.cppreference.com/w/cpp/language/operator_precedence or use google.
Upvotes: 1
Reputation: 132994
Operator precedence is the key here. Because &&
has higher precedence than ||
, your expression is equivalent to
(var1 && bool1) || (bool2 && var1->DoSomething() )
So, since var1
evaluates to false, bool1
is not evaluated and (var1 && bool1)
yields false, therefore (bool2 && var1->DoSomething())
has to be evaluated. And if bool2
happens to be true, then var1->DoSomething()
will also be evaluated, resulting in undefined behavior.
Just add some parentheses (for the specific expression tree that you require) and you'll be fine.
Upvotes: 12