2015-01-27 2 views
0

Это хорошо для меня, чтобы предположить в C или C++ или JavaScript или любой другой современный язык, что если я делаю ...C++ оптимизация логическое выражение

bool funt1(void) {…} 
bool funt2(void) {…} 
if (funt1() && funt2()) {Some code} 

... Могу ли я гарантировать, что обе функции вызываются или если funt1 возвращается false может ли компилятор поручиться на меня и никогда не звонить funt2?

+3

в большинстве языков - если funt1 возвращает ложь, второй не будет называться –

+7

[оценка короткого замыкания] (http://en.wikipedia.org/wiki/Short-circuit_evaluation) – quantdev

+1

Почему нет короткого замыкания в C++ для перегруженных операторов: http://stackoverflow.com/questions/25913237/is-there-actually-a-reason-why-overloaded-and-dont-short-circuit – Deduplicator

ответ

3

В C, C++ и Java-логические операторы и &&|| короткого замыкания, то есть в A && B, A сначала вычисляется и B вычисляется, если и только если A возвращается true. Аналогично, в A || B, B оценивается тогда и только тогда, когда A возвращается false. Они гарантированы языковыми стандартами и применяются, даже если B имеет побочные эффекты (на самом деле это можно использовать для контроля этих побочных эффектов).

В C++ эти правила применяются только к логическим операторам, применяемым к встроенным типам, но не к определяемым пользователем логическим операциям с тем же именем. Однако в вашем фрагменте кода сравниваются два bool, поэтому это не может быть определено пользователем &&.

+0

Теперь нам просто нужен пример «современного» языка, где короткое замыкание не используется ... – Deduplicator

+2

@Deduplicator Согласно сайту Wikipedia, связанному с комментарием квантова, [MUMPS] (http://en.wikipedia.org/ wiki/MUMPS) не имеет короткого замыкания, но я ничего не знаю об этой болезни (в том числе, поддерживает ли она операторов 'AND' и/или' OR'). Однако практически любой компьютерный язык имеет оценку короткого замыкания на этих двух операторах. – Walter

+0

Единственное, что я знаю об этом (слухи), подтверждает эту характеристику. Но вот подсказка: перегрузка оператора C++. – Deduplicator

1

Вы спросили:

Am I гарантирует, что обе функции вызываются или если funt1 возвращает false может компилятор под залог на меня и не называют funt2?

Если funt1() возвращает false, это гарантирует, что funt2() никогда не будет вызван.

Если funt1() возвращает true, то гарантировано, что funt2() будет вызван.

2

В C++ есть ошибка: если первая и вторая функции возвращают объекты, и оба они необходимы для логической операции, короткого замыкания нет.

#include <iostream> 

struct A {}; 
struct B {}; 

bool operator || (const A&, const B&) { return true; } 

A a() { std::cout << "A\n"; return A(); } 
B b() { std::cout << "B\n"; return B(); } 

bool f() { std::cout << "f\n"; return true; } 
bool g() { std::cout << "g\n"; return true; } 

int main(int argc, char* argv[]) 
{ 
    if(a() || b()); 
    if(f() || g()); 
} 
+0

Только когда оператор перегружен, не так ли? – Brian

+0

Фактически, когда оператор перегружен. Один из них не оказывает никакого влияния на конечный результат, ничего не меняет. Бесстыдный штекер вопроса, на который я ответил, о возможности разрешить перегруженным операторам короткое замыкание: https://stackoverflow.com/a/25913422 – Deduplicator

Смежные вопросы