当前位置: 首页 > 知识库问答 >
问题:

为什么C++编译器不将这种条件布尔赋值优化为无条件赋值呢?

顾正初
2023-03-14
void func(bool& flag)
{
    if(!flag) flag=true;
}
void func(bool& flag)
{
    flag=true;
}

然而,gcc和clang都没有这样优化它--它们都在-O3优化级别生成以下内容:

_Z4funcRb:
.LFB0:
    .cfi_startproc
    cmp BYTE PTR [rdi], 0
    jne .L1
    mov BYTE PTR [rdi], 1
.L1:
    rep ret

我的问题是:是因为代码太特殊而不需要优化,还是因为标志不是对volatile的引用,所以不需要这样的优化?似乎唯一的原因可能是标志可能有一个非true-或-false值,但在读取它时没有未定义的行为,但我不确定这是否可能。

共有1个答案

夔波
2023-03-14

由于缓存一致性的考虑,这可能会对程序的性能产生负面影响。每次调用func()时写入flag都会弄脏包含的缓存行。无论写入的值与写入前在目标地址找到的位完全匹配,都会发生这种情况。

编辑

hvd提供了另一个阻止这种优化的好理由。这是一个反对所建议的优化的更有说服力的论点,因为它可能导致未定义的行为,而我(最初)的回答只涉及性能方面。

const bool foo = true;

int main()
{
    func(const_cast<bool&>(foo));
}
 类似资料:
  • 我很难理解为什么要编译以下代码: 我可以理解为什么第一个赋值是有效的-

  • 我是JQUERY新手,假设我在php中dd()后面有一个数组,它显示如下数组:1[0=>"1,18,187,188,189,190,191,192,194,199,196,199,199,199,200,201,202,204,205,206,207,208,209,210,211,212,19,20,21,22,23,24"]现在我喜欢循环数组,只传递那些大于200值;这是密码 其中#UserD

  • 输出为“假”,但为什么?我将<code>truetruevs什么时候合适? 编辑:一些用户提到我应该看到错误,但我没有。我在PowerShell 2.0(Windows 7)和PowerShell 4.0(Windows 8.1)中都尝试过。和确实像我说的那样更改了COM属性。 编辑:事实证明,我们将< code>true赋给了COM属性,但它们实际上收到了false。我们的路径中有gnuwin3

  • 我注意到,当我使用条件断点进行调试时,执行速度会大大减慢。我知道这一点已经有一段时间了,现在想明白为什么。到底是什么原因导致执行如此缓慢?我知道正在添加一个条件,但是如果我自己添加条件,我不会减慢执行速度。 例如,假设我们有以下代码。假设我们添加了一个条件断点。让我们将条件设置为i==10000。 现在让我们自己写条件。 90秒完成击球(包括开始的9秒) 日食: ~9秒到达断点 第二个示例几乎是在

  • 在Rust中,在“if-else”构造中,创建或将多个对象之一指定给变量的首选方式是什么?由于范围限制,似乎必须在if-else之外创建变量。我想到的两种方式都不太好。以字符串为例,这里有一种方法,但它会生成一个关于未使用的赋值的警告: 另一种选择是: 它更短,并且不生成警告,但是意味着被分配了两次,并且意味着运行,但是如果为真,则会被浪费。如果不是简单的字符串创建,这些都是昂贵的操作(可能有副作