0

Is there any option in VS C++ 2017 so that when it builds the following program both f() and g() are called?

#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);
}
Swordfish
  • 12,971
  • 3
  • 21
  • 43

4 Answers4

10

Short circuit evaluation is part of the language specification. You can't just turn it off. You could instead assign f() and g() calls to variables and then evaluate those:

bool f_ret = f();
bool g_ret = g();
if (f_ret || g_ret)
    cout << "hello"; 
Mureinik
  • 297,002
  • 52
  • 306
  • 350
2

No there is not, this behavior (short-circuiting) is fundamentally part of logical operators.

What you can do instead is use the bitwise or operator |. But make sure to add a comment stating that this is not a mistake but on purpose!

In any case, if your function calls are not as simple as f() you should consider instead introducing a separate variable (or variables) to make it more obvious what your code is doing (calling two functions unconditionally, then using both their return values).

Pezo
  • 1,458
  • 9
  • 15
  • Comments can get out of sync with code (e.g. if something changes, programmers are notorious for not updating comments to match the intent of the code). As a rough rule, relying on comments to explain that code is not mistaken, even if it looks like a mistake, is a good reason not to use that code. Introducing "a separate variable (or variables)" is actually a more correct and less error-prone solution to the problem. – Peter Nov 02 '18 at 23:03
2

If you have at least one of your functions return a UDT with an operator|| defined:

#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";
}

both sides will be evaluated.

But. You. Don't. Want. To. Do. That.*)

*) unless the goal is to write obfuscated code ;)

Swordfish
  • 12,971
  • 3
  • 21
  • 43
  • Your `operator||()` would be more applicable if it accepted an argument of type `my_bool` and returns `my_bool`. As is, `f() || x() || y()` where `x()` and `y()` each return `bool` would not call `y()`, which is not quite what is expected of the solution. – Peter Nov 02 '18 at 22:14
  • @Peter. Right. Changed. – Swordfish Nov 02 '18 at 22:16
2

The probably simplest solution is writing:

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

Output:

f
g
hello

Operator + does not have any "short circuit evaluation". Logically, expression f() + g() is equivalent to f() || g() for the following reason: Operands of operator + are converted to integral values, where a false gives 0, and a true gives 1. The result of f() + g() is then in the range between 0..2. As this integral result is used where a boolean value is expected, it is converted back to boolean, whereby 0 is treated as false and everything >0 is treated as true.

Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58
  • 1
    Might get a bit of a shock with this solution if any functions being added return something other than `bool`. Consider what happens if `g()` is changed for some reason to return `int`, and to return values of `0`, `1`, or `-1` under specified conditions. For all cases where it returns `-1`, `f() + g()` will return give a result of `0`, even if `f()` returns `true`. – Peter Nov 02 '18 at 23:09