メインコンテンツ

AUTOSAR C++14 Rule A18-9-3

The std::move shall not be used on objects declared const or const&

説明

ルール定義

std::move は、const または const& を宣言したオブジェクトに対して使用しないものとします。

根拠

オブジェクトに対して std::move() を使用すると、rvalue にキャストされます。コンパイラは、最も近いパラメーター リストをもつコンストラクターまたは演算子を呼び出すことによってオブジェクト内のリソースを管理します。const または const& 型のオブジェクトに対して std::move() を呼び出すと、const または const& 型の rvalue が返されます。移動コンストラクターまたは演算子は const 型の引数を取得しないため、コンパイラは移動コンストラクターまたは演算子の代わりにコピー コンストラクターまたは演算子を呼び出します。std::move() の呼び出し後に移動を想定していた状態で const オブジェクトがコピーされる次のコード スニペットを考えてみましょう。

class string{
	//...
public:
	string(const string& rhs);// copy contructor
	string(string&& rhs);     //move constructor
};

void print(string text) {
	cout<<text;
	//...
}

int main(){
	int const message = "Error";
	//..
	print(std::move(message))// the copy constructor is called
}
std::move(message) の戻り値の型は、rvalue const string&& です。クラス string の移動コンストラクターとコピー コンストラクターでは、コピー コンストラクターだけが const 型の引数を受け入れます。コンパイラは、コピー コンストラクターを呼び出して、message のリソースを text にコピーします。

std::move()const または const& 型のオブジェクトを移動しないため、const または const& オブジェクトに対する std::move() の使用は避けてください。オブジェクトからリソースを移動する場合は、オブジェクトを const または const& として宣言しないでください。

Polyspace 実装

Polyspace® は、以下に対する std::move() の使用にフラグを設定します。

  • const または const& として宣言されたオブジェクト。

  • const または const& にキャストされたオブジェクト。

トラブルシューティング

ルール違反が想定されるものの、Polyspace から報告されない場合は、コーディング規約違反が想定どおりに表示されない理由の診断を参照してください。

すべて展開する

#include <cstdint>
#include <utility>
class A
{
	// Implementation
};
void F1(const int32_t &is_const, int32_t &is_non_const)
{
	const A a1{};
	int32_t target = 0;
	A a2 = a1;              // Compliant
	A a3 = std::move(a1);   // Noncompliant
	
	target = 
	std::move((const int32_t &)is_non_const);// Noncompliant
	target = 
	std::move(static_cast<const int32_t &>(is_non_const));// Noncompliant 
	target = 
	std::move(const_cast<int32_t &>(is_const));// Compliant
}
int main(){
	//...
}

  • Polyspace は、std::move()const オブジェクト a1 で使用した場合にフラグを設定します。コンパイラは、コピー コンストラクターを呼び出して、a1a3 にコピーします。コンパイラが移動コンストラクターを呼び出すと想定していたかもしれません。

  • Polyspace は、const にキャストされた is_non_const オブジェクトで std::move() を使用した場合にもフラグを設定します。キャスト後に、コンパイラは、コピー コンストラクターを呼び出して、is_non_consttarget にコピーします。コンパイラが移動コンストラクターを呼び出すと想定していたかもしれません。

  • Polyspace は、const_cast を使用して const オブジェクト is_const を非 const 型にキャストしたことにより行われた、非 const オブジェクトでの std::move() の使用にはフラグを設定しません。キャスト後は、is_constconst オブジェクトではなくなります。コンパイラは移動コンストラクターを呼び出します。

チェック情報

グループ: 言語サポート ライブラリ
カテゴリ: Required、Automated

バージョン履歴

R2020a で導入