如果 `v` 是一个类,`v + 1 - 1` 可以被编译器优化为 `v` 吗?

Hri*_*sip 4 c++

考虑以下代码:

struct S{
    int a, b;
    S() : a(0), b(10) {}
};

S operator + (const S& v, int n){
    S r = v;
    r.a += n;
    return r;
}
S operator - (const S& v, int n){
    S r = v;
    r.b -= n;
    return r;
}

S v = S() + 1 - 1;
Run Code Online (Sandbox Code Playgroud)

是否有可能S() + 1 - 1将优化为S()

编译器如何确定何时可以优化此类事情?

cig*_*ien 8

不,不允许编译器优化

S() + 1 - 1
Run Code Online (Sandbox Code Playgroud)

进入

S()
Run Code Online (Sandbox Code Playgroud)

因为这两个表达式对于您的 class 并不等效S

即使它可能是非惯用的,S按照您的方式编写也是完全有效的,operator+并且operator-不会相互抵消(在您的情况下,通过修改 2 个运算符中的不同成员变量)。

编译器需要在对 的计算S() + 1使用该结果之前进行计算- 1,并且只有在可以证明结果表达式相同的情况下才允许优化该表达式。换句话说,程序必须遵循as-if规则。显然,在这种情况下,结果会有所不同,因此不允许进行优化。


出于同样的原因,如果编译器可以看到一个表达式(它可以是任何表达式)等价于某个其他表达式,那么它就可以根据需要对其进行优化。但同样,编译器必须遵守as-if规则,即结果程序的行为必须完全就像根本没有进行任何优化一样。


请注意,虽然S根据语言规则您的实现是有效的,但它很奇怪,并且会让类的用户感到惊讶。我建议只在这样做了,是非常清楚域特定类型,并且其中类型的用户自然想到的是+-不一定是对方的逆。