Выключить || оптимизация оператора - PullRequest
0 голосов
/ 03 ноября 2018

Есть ли какая-либо опция в VS C ++ 2017, чтобы при сборке следующей программы вызывались и f(), и g()?

#include <iostream>
using namespace std;
bool f()
{
    cout << "f" "\n";
    return true;
}
bool g()
{
    cout << "g" "\n";
    return false;
}
int main()
{

    if (f() || g())
        cout << "hello";
    cin.ignore(1);
}

Ответы [ 4 ]

0 голосов
/ 03 ноября 2018

Вероятно, самое простое решение - написать:

if (f()+g())
    cout << "hello";

Выход:

f
g
hello

Оператор + не имеет никакой "оценки короткого замыкания". Логически выражение f() + g() эквивалентно f() || g() по следующей причине: операнды оператора + преобразуются в целочисленные значения, где false дает 0, а true дает 1. Результат f() + g() находится в диапазоне между 0..2. Поскольку этот интегральный результат используется там, где ожидается логическое значение, он преобразуется обратно в логическое значение, в результате чего 0 обрабатывается как false, а все >0 обрабатывается как true.

0 голосов
/ 03 ноября 2018

Оценка короткого замыкания является частью спецификации языка. Вы не можете просто выключить это. Вместо этого вы можете назначить f() и g() вызовы переменных, а затем оценить их:

bool f_ret = f();
bool g_ret = g();
if (f_ret || g_ret)
    cout << "hello"; 
0 голосов
/ 03 ноября 2018

Если у вас есть хотя бы одна из ваших функций, возвращайте UDT с определенным operator||:

#include <iostream>

struct my_bool
{
    bool value;
    my_bool(bool value) : value{ value } {}
    operator bool() const { return value; };
    my_bool operator||(my_bool rhs) const { return value || rhs.value; }
};

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

my_bool g()
{
    std::cout << "g()\n";
    return false;
}

int main()
{

    if (f() || g())
        std::cout << "hello\n";
}

обе стороны будут оцениваться.

Но. Вы. Не. Хочу. Для. Делать. Это. *)

*), если цель не состоит в том, чтобы написать запутанный код;)

0 голосов
/ 03 ноября 2018

Нет, это поведение (короткое замыкание) является фундаментальной частью логических операторов.

Вместо этого вы можете использовать побитовый оператор или оператор |. Но обязательно добавьте комментарий о том, что это не ошибка, а намеренно!

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

...