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

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

пример:

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

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

Этот тип оценки называется короткозамкнутым . Если результат на 100% ясен, он не будет продолжать оценивать.

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

 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 , то он не будет увеличиваться вообще.

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

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

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

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

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

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