メインコンテンツ

AUTOSAR C++14 Rule A8-4-14

Interfaces shall be precisely and strongly typed

説明

ルール定義

Interfaces shall be precisely and strongly typed.

根拠

インターフェイスはオブジェクトの動作または機能を記述します。正確かつ厳密に型指定されたインターフェイスでは、基本型ではなくカスタム オブジェクトとテンプレートであるパラメーターを使用して、パラメーターの目的とプロパティを指定します。以下のコード スニペットのインターフェイスを比較してください。

void draw_circle(float R, float x, float y);
void draw_circle(Length R, Position O);
どちらのインターフェイスも円を描画する関数を表現しています。最初のインターフェイスは入力パラメーターとして 3 つの浮動小数点数を使用します。2 番目のインターフェイスでは、入力パラメーターとしてクラス Length のオブジェクトとクラス Position のもう 1 つのオブジェクトを使用します。

  • 2 番目のインターフェイスでは、最初のパラメーターが長さで、2 番目のパラメーターが位置であることが明示されています。このインターフェイスは簡単に理解して使用できます。特定の円に対する必須入力パラメーターとその順序が強調表示されるためです。対照的に、最初のインターフェイスでは入力パラメーターとその順序を判別できません。3 つの浮動小数点数と円の関係が不明確だからです。

  • コンパイラは、コンパイル時に引数を入力パラメーターの型に対してチェックします。2 番目のインターフェイスで入力パラメーターを間違った順序で指定した場合、コンパイラはコンパイル時に一致しないパラメーターにフラグを設定します。最初のインターフェイスの 3 つの入力パラメーターがすべて浮動小数点数である場合、コンパイラは入力順序が正しいかどうかをチェックできません。

  • クラス LengthPosition の定義では、これらのパラメーターの単位 (cm、mm など) を指定できます。クラス定義では、これらのパラメーターが不変かどうかを指定することもできます。入力パラメーターに基本型を使用すると、そのような指定は困難です。

基本型の入力パラメーターを使用しているため、最初のインターフェイスはあいまいで、間違いが発生する可能性があります。多数の基本型パラメーターを持つインターフェイスの使用は避けてください。代わりに正確かつ厳密に型指定されたインターフェイスを使用します。コンパイラは多くの場合、型指定の弱いインターフェイスよりも、このようなインターフェイスを適切に最適化できます。

複数のパラメーターが関係する場合、それらを組み合わせてユーザー定義型にします。ポリモーフィック インターフェイスを実装する場合、void へのポインター (void*) ではなく共通基底クラスへのポインターを使用します。汎用インターフェイスの場合、パラメーターとしてテンプレートを使用します。

Polyspace 実装

Polyspace® では以下の型が "基本型" です。

  • intshortlong などの整数型

  • floatdouble などの浮動小数点型

  • boolean (bool) 型

  • void へのポインター (void*)

  • 前述の型へのポインターまたは参照

  • 前述の型の typedef

  • 前述の型の配列

Polyspace では列挙型 (enums) は基本型ではありません。Polyspace は、入力パラメーターに以下のいずれかが含まれる場合、インターフェイスにフラグを設定します。

  • 1 個以上の void 関連型

  • 2 個以上の bool 関連型

  • 3 個以上の同一基本型

コメントやパラメーター名などの代替手段を使用してインターフェイス定義を明確にすることができます。このような場合、結果またはコード内でコメントを使用することにより Polyspace の結果を正当化できます。Polyspace ユーザー インターフェイスでのバグ修正または正当化による結果への対処を参照してください。

トラブルシューティング

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

すべて展開する

Polyspace は、入力パラメーターに以下が含まれる場合、インターフェイスにフラグを設定します。

  • 2 個以上の bool 関連型

  • 3 個以上の同一基本型

以下のコードのインターフェイスについて考えます。

#include <cstdint>
#include <chrono>

void Sleep(std::uint32_t duration);//Compliant

void SetProperty(bool Status);//Compliant

void SetAlarm(std::uint32_t year, std::uint32_t month, //Noncompliant
              std::uint32_t day, std::uint32_t hour,
              std::uint32_t minute, std::uint32_t second);

//Compliant
void StartClock(std::chrono::system_clock::time_point const& when);
typedef struct {
    int a, b, c, d;
} Point;
void Triangle(float a, float b, float c);//Noncompliant
void Rectangle(Point a, Point b, Point c, Point d); //Compliant

main()
{
    //...
}

  • Polyspace は、SetAlarm()Triangle() のように 3 個以上の基本型変数を入力パラメーターとして使用するインターフェイスにフラグを設定します。

  • インターフェイス StartClock()Rectangle() では正確かつ厳密に型指定された入力パラメーターを使用しています。Polyspace はこれらのインターフェイスにフラグを設定しません。

  • Polyspace は、3 個未満の基本型入力パラメーター、または 2 個未満の bool 型入力パラメーターを持つインターフェイスにはフラグを設定しません。

Polyspace は、入力パラメーターに void へのポインター (void*) が 1 つ以上含まれる場合、インターフェイスにフラグを設定します。以下のコードのインターフェイスについて考えます。

#include <cstdint>

class A{
	//...
};
class B:public A{
	//...
};
class C:public A{
	//...
};

void polymorphic_function(void*);//Noncompliant
void polymorphic_function(A*);//Compliant

void printArray(void* Array);//Noncompliant
template <typename T>
void printArray (T* Array);//Compliant

main(){
	//...
}

すべてのポインター型は暗黙的に void* に変換されます。これは弱い非修飾型です。void* ポインターの使用を避けます。

  • ポリモーフィック インターフェイスを実装するには、void* ではなく A* などの基底クラスへのポインターを使用します。

  • 汎用インターフェイスを実装する場合、void* ではなく T* などのテンプレートを使用します。

チェック情報

グループ: 宣言子
カテゴリ: Required、Non-automated