Оценка короткого замыкания C ++ - PullRequest
2 голосов
/ 14 января 2012

Может быть, я упускаю что-то довольно простое, но у меня возникает сбой при разыменовании указателя, даже если я проверяю точку в самом начале выражения.

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

}

var1 - нулевой указатель, но Var1-> Dosomething () все еще вызывается. Я понимаю, что && и || Операторы в C ++ имеют короткое замыкание, поэтому, если var1 был нулевым, он просто завершился бы в самом начале. Или мне чего-то не хватает?

Ответы [ 3 ]

12 голосов
/ 14 января 2012

Приоритет оператора является ключевым здесь.Поскольку && имеет более высокий приоритет, чем ||, ваше выражение эквивалентно

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

Итак, поскольку var1 оценивается как ложное, bool1 не оценивается и (var1 && bool1) дает ложное значение, поэтому(bool2 && var1->DoSomething()) должен быть оценен.И если bool2 окажется истинным, то var1->DoSomething() также будет оцениваться, что приведет к неопределенному поведению.

Просто добавьте несколько скобок (для нужного вам дерева выражений), и все будет в порядке.

2 голосов
/ 14 января 2012

Поскольку && имеет более высокий приоритет, чем ||, ваше выражение анализируется как (var1 && bool1) || (bool2 && var1->DoSomething()).Теперь, поскольку var1 является нулевым указателем, оценка короткого замыкания означает, что bool1 не оценивается, а левая часть || оценивается как ложная.Таким образом, чтобы узнать значение выражения, необходимо оценить правую часть (т. Е. При оценке короткого замыкания не здесь!).Правая часть || равна bool2 && var1->DoSomething(), поэтому, если bool2 истинно, var1->DoSomething() будет оцениваться.Также обратите внимание, что даже для var1 не ноль, результат выражения не всегда будет тем, что вы, вероятно, ожидали.

1 голос
/ 14 января 2012

Simple. && имеет более высокий приоритет, поэтому ваше выражение выглядит так:

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 или используйте Google.

...