编译器可以简化涉及函数的逻辑表达式吗?

发布于 2024-12-02 10:03:50 字数 510 浏览 1 评论 0原文

一些计算布尔值的函数:

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();
}

Some functions which calculate booleans:

bool a()
{
   return trueorfalse;
}

bool b()
{
   //...
}

bool c()
{
   //...
}

This condition

//somewhere else
if((a()&&b()&&c()) || (a()&&b()&&!c()) )
{
    doSomething();
}

can also be written as

if(a()&&b())
{
   doSomething();
}

Will compilers usually optimize this away?

And what about pure boolean values:

if((a&&b&&c) || (a&&b&&!c))
{ 
   doSomething();
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

虚拟世界 2024-12-09 10:03:50

由于函数可能有副作用,因此不能以任何方式“优化”条件,因为所有函数都必须以明确定义的方式(有条件地)调用。

如果您确实想要优化,可以先将结果分配给变量:

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)
{
  // ...
}

Since the functions may have side effects, the conditional cannot be "optimized" in any way, since all the functions will have to be called (conditionally) in a well-defined manner.

If you do want optimization, you can assign the result to variables first:

const bool ba = a(), bb = b(), bc = c();

if (ba && bb && bc || ba && bb && !bc) { /* ... */ } // probably optimized to "ba && bb"

It's possible that constexpr functions introduced in C++11 will allow for optimization if they yield a constant expression, though, but I'm not sure.

You can even condense this down: In the following code, f() has to be called twice:

if (f() && false || f() && true)
{
  // ...
}
⊕婉儿 2024-12-09 10:03:50

不,他们不会。原因是优化对用户来说是可见的,因为它会改变可观察到的副作用。例如,在您的优化版本中,即使用户明确尝试这样做,c()也永远不会执行。这可能而且将会导致错误。

No they won't. The reason why is that the optimization would be visible to the user because it would change the observable side effects. For example In your optimized version c() would never execute even though the user explicitly tried to do so. This can and will lead to bugs.

紫竹語嫣☆ 2024-12-09 10:03:50

既然你的前提有缺陷,不,他们不会。

<代码>(a()&&b()&&c()) || (a()&&b()&&!c()) 绝对不能重写为 (a()&&b())

C(和 C++)不是函数式编程语言(如 Haskell)。

Since your premise a flawed, no, they won't.

(a()&&b()&&c()) || (a()&&b()&&!c()) definitely can't be rewritten as (a()&&b())

C (and C++) isn't a functional programming language (like Haskell).

清君侧 2024-12-09 10:03:50

但问题是,一般来说,它不能以这种方式重构!

如果任何函数具有更改 c() 结果的副作用,则第二次调用可能会返回与第一次不同的结果。

不仅如此,由于执行短路,事情可能会变得更加混乱。

But the problem is that it can't be refactored in that way, generally speaking!

If any of the functions have side effects that change the result of c() then the second call would possibly return a different result from the first one.

Not only that, but due to short-circuit execution things could be muddied even further.

要走就滚别墨迹 2024-12-09 10:03:50

在 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;
}

编辑变量的任何布尔代数都应该被简化。

Very often in C the return value of a function gives whether the function was executed successfully of not. For example calling a graphics routine, converting a file. Think how often you use pointers to change something external to the function. Or call another function that outputs something. As someone said this isn't functional programming.

If the compiler is able to determine that foo() changes and does nothing then it may by all means simplify it but I would NOT count on it.

Here is a very simple example

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

Edit any boolean algebra of variables should be simplified.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文