计算布尔值的一些函数:
bool a()
{
return trueorfalse;
}
bool b()
{
//...
}
bool c()
{
//...
}
这个条件
//somewhere else
if((a()&&b()&&c()) || (a()&&b()&&!c()) )
{
doSomething();
}
也可以写成
if(a()&&b())
{
doSomething();
}
编译器通常会优化它吗?
纯粹的布尔值怎么样:
if((a&&b&&c) || (a&&b&&!c))
{
doSomething();
}
答案 0 :(得分:4)
由于函数可能有副作用,因此无法以任何方式“优化”条件,因为必须以明确定义的方式(有条件地)调用所有函数。
如果您确实需要优化,可以先将结果分配给变量:
const bool ba = a(), bb = b(), bc = c();
if (ba && bb && bc || ba && bb && !bc) { /* ... */ } // probably optimized to "ba && bb"
C ++ 11中引入的constexpr
函数可能会在它们产生常量表达式时进行优化,但我不确定。
你甚至可以压缩它:在下面的代码中,f()
必须被调用两次:
if (f() && false || f() && true)
{
// ...
}
答案 1 :(得分:2)
不,他们不会。原因是用户可以看到优化,因为它会改变可观察的副作用。例如,在优化版本c()
中,即使用户明确尝试这样做,也永远不会执行。 可以而且会导致错误。
答案 2 :(得分:1)
由于你的前提是有缺陷的,不是,他们不会。
(a()&&b()&&c()) || (a()&&b()&&!c())
绝对不能改写为(a()&&b())
C(和C ++)不是函数式编程语言(如Haskell)。
答案 3 :(得分:1)
但问题是,不能以这种方式重构,一般来说!
如果任何一个函数的副作用改变了c()
的结果,那么第二个调用可能会返回与第一个函数不同的结果。
不仅如此,由于短路执行,事情可能会更加混乱。
答案 4 :(得分:1)
通常在C中,函数的返回值表示函数是否成功执行了。例如,调用图形例程,转换文件。想想你经常使用指针来改变函数外部的东西。或者调用另一个输出内容的函数。有人说这不是函数式编程。
如果编译器能够确定foo()发生了变化并且什么也没做,那么它可能无论如何都会简化它,但我不会指望它。
这是一个非常简单的例子
bool foo()
{
std::cout << "this needs to be printed each time foo() is called, even though its called in a logical expression\n";
return true;
}
int main()
{
if ((foo() && !(foo()) || foo() && !(foo())))
return 0;
return 1;
}
编辑任何变量的布尔代数都应该简化。