メインコンテンツ

AUTOSAR C++14 Rule A8-4-5

"consume" parameters declared as X && shall always be moved from

R2021a 以降

説明

ルール定義

"consume" parameters declared as X && shall always be moved from.

根拠

関数を宣言するとき、関数パラメーターを非定数で非テンプレートの rvalue 参照または "consume" (X&&) パラメーターとして宣言することにより、そのパラメーターの内容を移動する意図を示すことができます。たとえば、関数 void foo(std::vector<std::string>&& V) のパラメーターは "consume" パラメーターとして宣言されています。この宣言では、関数の本体内でベクトル V の内容の、コピーではなく移動が意図されていることが暗黙のうちに示されています。

関数パラメーターを "consume" パラメーターとして宣言する場合は、パラメーター使用時に移動セマンティクスを使用します。関数呼び出しに lvalue 参照を使用している場合、関数の本体内では関数 std::move を明示的に使用します。

Polyspace 実装

Polyspace® は、以下の条件を両方とも満たす場合に、関数の定義にフラグを設定します。

  • 少なくとも 1 つの関数パラメーターが非定数で非テンプレートの rvalue 参照、すなわち "consume" (X&&) パラメーターとして宣言されている。

  • X&& パラメーターの内容を、関数の本体内で関数 std::move を使用して別のオブジェクトに完全には移動していない。

Polyspace は、移動コンストラクターおよび移動代入演算子に対して、このルールの違反を報告しません。

トラブルシューティング

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

すべて展開する

この例では、クラス C のデータ メンバー a が、移動セマンティクスを使用して整数に設定されています。

#include <utility>
class C
{
	C(C&& c): a{std::move(c.a)}     // Compliant by exception.
	{
	}

	C& operator=(C&& c)             // Compliant by exception.
	{
		a = std::move(c.a);

		return *this;
	}

	void move(C&& c)                
	{
		a = std::move(c.a);//Partial move
	}

	void cond(C&& c, bool b)        // Compliant
	{
		if (b) {
			move(std::move(c));
		} else {
			a++;
		}
	}
public:
	int a;
	void set(int&& num)     // Compliant
	{
		a = std::move(num);
	}
	void set1(int&&)     // Noncompliant
	{
		//Unnamed temporary variable cannot be moved from.
	}
	void set2(int&& i12);  // Violation raised on definition.
	void set3(int&& i11a,  // Noncompliant
	int&& i11b)  // Noncompliant
	{
		if(i11a != i11b)
		{
		}
	}
	
};
void C::set2(int&& i12)   // Noncompliant
{
	a = i12;
}

template<typename T>
void tf1(T&& t1)      // Compliant - not a "consume" parameter
{
}

  • Polyspace は、移動コンストラクターと移動代入演算子が "consume" (X&&) パラメーターを完全に移動するわけではなくても、これらの関数にフラグを設定しません。このような関数は例外として準拠します。

  • Polyspace は関数 C::set1 にフラグを設定します。この関数は無名 "consume" パラメーターを使用しているからです。パラメーターは無名なので、この X&& パラメーターに対して関数 std::move を使用できません。

  • Polyspace は関数 C:: set2 にフラグを設定します。関数の本体では関数 std::move を使用するのではなく "consume" パラメーターをコピーしているためです。Polyspace は変数の定義について違反を報告します。同様に、関数 C::set2 もこのルールに非準拠です。本体では変数 X&&std::move を使用していないためです。

  • 関数 C::condC::set はこのルールに準拠しています。これらの関数の本体では "consume" パラメーターに std::move を使用しているからです。

  • Polyspace は関数テンプレートにはフラグを設定しません。このルールはテンプレートには適用されないからです。

チェック情報

グループ: 宣言子
カテゴリ: Required、Automated

バージョン履歴

R2021a で導入