使用 const ref 参数进行自赋值的行为



我偶然发现了一些非常古老的代码,其中有一个带有定义的复制赋值运算符的类,该运算符将其参数作为常量引用,但也不检查自赋值,因此本质上:

struct A
{
    int q;
    A(): q(3) {}
    A& operator=(const A& a)
    {
        q = a.q;
        return *this;
    }
};

A的实例分配给自身时,此赋值运算符的行为是什么?我认为这会导致问题,因为它"破坏"了参数的恒定性,任何编译器都可以假设参数没有更改并基于此进行优化。

但是,clang和gcc都不会发出警告,并且程序运行良好。如果我在赋值运算符中的赋值之前将 q 的值显式更改为 4,这也有效。

将对象绑定到 const 引用不会让它突然变得 const。那里的const仅表示函数无法通过 a 修改参数。这并不意味着引用的对象必须是常量本身。

由于 *thisa 可以合法地为同一对象设置别名,因此此类代码没有风险。编译器不能对别名做出疯狂的假设。

仅当赋值运算符未运行完成或释放然后尝试从"其他"复制的资源时,对象状态可能会以某种方式损坏时,自赋值才是一个问题。您的示例没有发生这种情况的风险。然而,一般来说,人们应该注意可能引发的异常和资源的所有权。

最新更新