Подтвердить что ты не робот

Порядок выполнения для if с несколькими условными обозначениями

В выражении if с несколькими условными выражениями, является ли второе условие выполненным, если результат первого ясен?

Пример:

if(i>0 && array[i]==0){
}

Если я поменяю условные выражения, может возникнуть segfault для отрицательных значений i, но при этом не возникает segfault. Могу ли я быть уверенным, что это всегда работает или нужно использовать вложенные операторы if?

4b9b3361

Ответ 1

Этот тип оценки называется short-circuiting. Когда результат будет на 100% понятен, он не продолжит оценку.

Это на самом деле общий метод программирования. Например, в С++ вы часто увидите что-то вроде:

if (pX!=null && pX->predicate()) { bla bla bla }

Если вы изменили порядок условий, вы можете вызвать метод с нулевым указателем и сбой. Аналогичный пример в C будет использовать поле структуры, если у вас есть указатель на эту структуру.

Вы можете сделать что-то подобное с помощью или:

if(px==null || pX->isEmpty()} { bla bla bla }

Это также одна из причин, по которой, как правило, рекомендуется избегать побочных эффектов в условии if.

Например, предположим, что у вас есть:

if(x==4 && (++y>7) && z==9)

Если x - 4, то y будет увеличиваться независимо от значения z или y, но если x не 4, он не будет увеличиваться вообще.

Ответ 2

Операторы && и || гарантируют, что левое выражение будет полностью оценено (и все побочные эффекты) до того, как будет оценена правая часть. Другими словами, операторы вводят точку последовательности.

Кроме того, если значение выражения можно определить из lhs, rhs не оценивается. Другими словами, если у вас есть выражение типа x && y, а x оценивается как 0 (false), то значение выражения ложно независимо от y, поэтому y не оценивается.

Это означает, что выражения типа x++ && x++ четко определены, так как && вводит точку последовательности.

Ответ 3

Из проекта 3485 (n3485.pdf) В нем четко указано, что

5.14 Логический оператор AND [expr.log.and]

logical-and-expression: 
      inclusive-or-expression
      logical-and-expression && inclusive-or-expression 
  • && группы операторов слева направо. операнды преобразуются в контекст в bool (раздел 4). результат равен true, если оба операнда истинны и false в противном случае. В отличие от &, && гарантирует оценку слева направо: второй операнд не является если первый операнд ложный.
  • В результате получается bool. Если вычисляется второе выражение, вычисляются все значения и стороны эффект, связанный с первым выражением, секвенирован перед каждым вычисление значения и побочный эффект, связанный со вторым выражение.