メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

AUTOSAR C++14 Rule A3-1-5

A function definition shall only be placed in a class definition if (1) the function is intended to be inlined (2) it is a member function template (3) it is a member function of a class template

説明

ルール定義

A function definition shall only be placed in a class definition if (1) the function is intended to be inlined (2) it is a member function template (3) it is a member function of a class template.

根拠

クラス定義内の関数定義の配置が許可されるのは、以下の場合のみです。

  • 関数がインライン化するように意図されている。クラス定義内にメンバー関数の定義を配置すると、コンパイラにメンバー関数のインライン化が指示されます。小さい関数をインライン化すると、関数呼び出しの実行時オーバーヘッドが回避され、コンパイル済みの実行可能ファイルのパフォーマンスが向上します。ただし、この暗黙的なインライン化に気付かずにクラス定義内に大きいメンバー関数の定義を配置すると、コンパイル済みの実行可能ファイルが大きくなりすぎる場合があります。

  • 関数がメンバー関数テンプレートまたはクラス テンプレートのメンバーである。これらのコーディング手法では、テンプレート構文要素 (パラメーター リストなど) の繰り返しが減少します。この減少によって、コードの可読性と保守性が向上します。

Polyspace 実装

inline キーワードが明示的に使用されない限りチェッカーは、ただ 1 つのステートメントからなる小さい関数のみがインスタンス化されるというヒューリスティックを利用します。また、チェッカーは次のように AUTOSAR C++14 Rule A3-1-5 を解釈します。

非テンプレート メンバー関数と非テンプレート クラスのメンバー関数の場合は、クラスの外部で定義された 1 行のメンバー関数とクラスの内部で定義されたより大きなメンバー関数に、チェッカーがフラグを設定します。

テンプレート メンバー関数とテンプレート クラスのメンバー関数の場合は、クラスの外部で定義されたすべてのメンバー関数にチェッカーがフラグを設定します。

Polyspace® は、関数 constexpr と関数 consteval でのこのルールに対する違反を報告しません。

トラブルシューティング

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

すべて展開する

#include <cstdint>
#include <iostream>

class A
{
	private:
	std::uint32_t val = 5;
	
	public:
	std::uint32_t Foo()  // Compliant with (1)
	{
		return val;
	}
	
	std::uint32_t Bar(); 
};

std::uint32_t A::Bar() // Noncompliant with (1)
{
	return (val + 5);
} 

std::uint32_t main()
{
	A a;
	std::cout << a.Foo() << std::endl;
	std::cout << a.Bar() << std::endl;
	return 0;
}

クラス A の定義の外部に Bar の定義を配置すると、ルールに違反します。これは、Bar が単一のステートメントで構成されているためです。

#include <cstdint>
#include <iostream>

class A
{
  public:
    template <typename T>     // Compliant with (2)
    void Foo(T t)
    {
      std::cout << "This function is defined inside with param: " 
      << t << std::endl;
    }

    template <typename T>     // Non-compliant with (2)
    void Bar(T t);
};


template <typename T>
void A::Bar(T t)
{
  std::cout << "This function is defined outside with param: " 
  << t << std::endl;
}

std::uint32_t main(void)
{
  A a;
  a.Foo<float>(3.14f);
  a.Bar<std::uint32_t>(5);
  return 0;
}

クラス A の定義の外部にメンバー関数テンプレート Bar の定義を配置すると、ルールに違反します。

#include <cstdint>
#include <iostream>

template <typename T>
class B
{
  public:
    B(const T x) : t(x) {}

    void display()   //Compliant with (3)
    {
      std::cout << t << std::endl;
    }

    void display2();   //Non-compliant with (3)

  private:
    T t;
};

template <typename T>
void B<T>::display2()
{
  std::cout << t << std::endl;
}

int main(void)
{
  B<std::int32_t> b(7);
  b.display();
  b.display2();
  return 0;
}

クラス テンプレート B の定義の外部にメンバー関数 display2 の定義を配置すると、ルールに違反します。

チェック情報

グループ: 基本概念
カテゴリ: Required、Partially automated

バージョン履歴

R2020b で導入

すべて展開する