CWARN.MOVE.CONST

定数値が引数として std::move() に渡されました

CWARN.MOVE.CONST チェッカーは、引数が const である C++ STL (Standard Template Libraries) からの std::move() メソッドの呼び出しのインスタンスを検出し、報告します。

脆弱性とリスク

オブジェクトで std::move() を呼び出して r値にキャストする処理は、一般にこのオブジェクトに対して移動処理を行うというプログラマーの意図を示します。しかし、const オブジェクトに対する移動要求は、自動的にコピー処理に変換されます。これは、const 修飾子がオブジェクトの変更を禁じているためです。このため、プログラマーが const オブジェクトで 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)};
}

const を削除すると、オブジェクトは予期どおり移動します。

修正コード例 2

コピーコンストラクターが予期される場合には、std::move() は余分であり、削除する必要があります。

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