Да, кроме правила as-if.
func1() && func2()
означает if (func1()) return true; else return func2()!=false;
приблизительно (return
здесь не настоящий «возврат», и это все одно выражение, поэтому только грубо). func1()?true:func2()
ближе к тому, что это означает.
C++ имеет правила короткого замыкания. &&
сначала оценивает левую сторону, затем, если он возвращает false
, тогда он оценивает правую сторону.
Но всегда есть исключения.
Если кто-то переопределил &&
для двух аргументов, обе стороны будут оценены до передачи &&
. Это хорошая причина не переопределять &&
.
Во-вторых, как если бы правило означает, что компилятор волен оценивать func2()
, если это было бы так, если вы не сделали этого, когда func1()
вернулся true
, и если когда func1()
возвращается false
он ведет себя так же как- если он был назван вторым. То есть, если нет способа, чтобы вызов func2()
мог быть «замечен», до неопределенного поведения.
Примером такого рода может быть строгий псевдоним, где func1()
изменяет некоторое значение, для которого нет определенного способа поведения для func2()
для его обнаружения. Но ожидается, что func2()
через неопределенное поведение (скажем, нарушение строгой псевдонимы) обнаружит изменение.
Если func2()
не имеет никакого другого взаимодействия с func1()
доказуема, и без каких-либо побочных эффектов, то func2()
может быть оценен до или после func1()
под как если бы правилом оптимизации. Это может быть полезно, потому что современные процессоры могут выполнять несколько операций одновременно (даже в одном «потоке» исполнения).
Если бы он на самом деле были оценены после, результат func2()
могло быть иначе, а потому, что зависимость зависит от неопределенного поведения компилятор разрешается путешествия во времени и не имеют результата вы ожидаете быть произведены.
Долгий и недостаток в том, что понимание C++, как будто это портативная сборка, недостаточна. Поэтому, пока func1()
должен быть вызван до func2()
логически в абстрактной машине, на которой работает C++, это не значит, что это нужно делать на аппаратном обеспечении, которое ваша программа действительно компилирует.
Если 'func2' должно использовать новое значение для' i', тогда 'func1' должен принимать входной параметр int-reference (' int & '). – Jonas