如果输出无关紧要,则不会调用函数

Qui*_*mby 1 c++ optimization function

我有以下代码:

#include <iostream> 

bool function(int a, int b, int &foo) {
    std::cout << "I have been called and I";
    if (a > b)// some magic that maybe changes 'foo'
    {
        foo++;
        std::cout << " did change the variable" << std::endl;
        return true;//inform that i have changed the value
    }
    std::cout << " did NOT change the variable" << std::endl;

    return false;
};

int main()
{
    bool changed = false;
    int bar = 0;
    for (size_t i = 0; i < 10; i++)
    {
        changed = changed || function(i,4,bar);
    }
    std::cout << "Bar:" << bar;
    std::cin.get();
    std::cin.get();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我有一个函数,它对两个变量做了一些魔术,这取决于它可能会改变foo变量.它也会返回bool,无论它是否改变了.

假设我把这个函数放在一个循环中.我称它为10次,我想知道这些调用是否改变了变量.所以我对上面代码的期望是:

I have been called and I did NOT change the variable
I have been called and I did NOT change the variable
I have been called and I did NOT change the variable
I have been called and I did NOT change the variable
I have been called and I did NOT change the variable
I have been called and I did change the variable// 'changed' is now true
I have been called and I did change the variable
I have been called and I did change the variable
I have been called and I did change the variable
I have been called and I did change the variable
Bar:5
Run Code Online (Sandbox Code Playgroud)

但不是.相反,我得到:

I have been called and I did NOT change the variable
I have been called and I did NOT change the variable
I have been called and I did NOT change the variable
I have been called and I did NOT change the variable
I have been called and I did NOT change the variable
I have been called and I did change the variable// 'changed' is now true
Bar:1
Run Code Online (Sandbox Code Playgroud)

在第五次调用中,变量发生了变化,这是正确的.但剩下的四个电话甚至没有发生.我明白了,因为第五次调用返回true,然后'changed'变量将始终为true,无论剩余的调用返回什么.我不在乎,我希望它能保持'真实',毕竟这是正确的.但我的观点是,剩下的四个调用可能会将'bar'变量更改为完全不同的值,我需要在循环后使用这个"正确更改"的值.

那么有人可以解释一下,为什么函数不被调用只是因为它的返回值无关紧要?因为我没有看到这意味着函数内部的代码也是无关紧要的,特别是当一些参数由非const引用传递时.(据我所知,该函数甚至可以完全终止程序.)

我不是在寻找解决方案,更像解释为什么会发生这种情况.

我使用VS 2015,标准DEBUG和RELEASE模式编译了这个,结果相同.

如果我消除'changed'变量并且只是在循环中调用函数,显然我得到了正确的输出.

Ale*_*exD 5

这是由于短路评估.

标准状态(强调我的):

5.15逻辑或操作
...
不像|,||左到右的担保评估; 此外,如果第一个操作数的计算结果为,则不计算第二个操作数true.

尝试交换参数:

changed = function(i,4,bar) || changed;
Run Code Online (Sandbox Code Playgroud)