CWARN.MOVE.CONST

常数值已作为参数传递至 std::move()

CWARN.MOVE.CONST 检查器会从参数为常数的 C++ 标准模板库 (STL) 中检测并报告对 std::move() 方法的调用实例。

漏洞与风险

调用对象上的 std::move() 以将其转换为右值,通常表示程序员打算对其执行移动操作。但是,移动常量对象的请求会静默地转换为复制操作,因为常量限定符禁止修改对象。因此,在常量对象上调用 std::move() 时,程序员希望调用的可能是移动操作,但程序执行的是复制操作。如果在预期调用的移动操作中存在代码,那么此举可能会造成更大的代价,或者导致难以发现错误。

代码示例

漏洞代码示例 1

复制
class X{
    /* custom copy and move constructors defined */
};
void foo(){
    const X bar;
    X quux = std::move(bar); //copy constructor is silently called here instead of expected move constructor
}

在以上示例中,Klocwork 会将表达式 std::move(bar) 报告为 CWARN.MOVE.CONST 缺陷。

修正代码示例 1

复制
class X{
    /* custom copy and move constructors defined */
};
void foo(){
    X bar;
    X quux{std::move(bar)};
}

删除常量即可按预期移动对象。

修正代码示例 2

或者,如果需要用到复制构造函数,那么 std::move() 便是多余的,应将其删除:

复制
class X{
    /* custom copy and move constructors defined */
};
void foo(){
    const X bar;
    X quux{bar};
}