メインコンテンツ

AUTOSAR C++14 Rule A7-1-5

The auto specifier shall not be used apart from following cases:(1) to declare that a variable has the same type as return type of a function call, (2) to declare that a variable has the same type as initializer of non-fundamental type, (3) to declare parameters of a generic lambda expression, (4) to declare a function template using trailing return type syntax

説明

ルール定義

The auto specifier shall not be used apart from following cases:(1) to declare that a variable has the same type as return type of a function call, (2) to declare that a variable has the same type as initializer of non-fundamental type, (3) to declare parameters of a generic lambda expression, (4) to declare a function template using trailing return type syntax.

根拠

変数宣言で auto 型指定子を使用すると、変数の型はコンパイラによって推定されます。コードを読む開発者は、型の推定が自分の想定と異なると混乱する可能性があります。型の推定に必要な情報はコードの別の部分にある可能性があります。

このルールでは、次の場合に auto 指定子の使用を許可します。

  • 関数呼び出しで初期化される変数を宣言している。これにより型の繰り返しが避けられ、関数の戻り値の型を変更しても想定外の変換は絶対に生じません。たとえば、以下のコード スニペットでは変数 varmyfunc() の戻り値の型と同じ型です。

    #include<cstdint>
    
    int32_t myfunc();
    
    int foo(){
      auto var=myfunc();
      return var;
    }

  • 非基本型初期化子を使用して初期化する変数を宣言している。std::is_fundatmental<T>::value が false である場合、T 型は非基本型です。基本型の一覧については、基本型を参照してください。たとえば、以下のコード スニペットの var の型は std::vector<int>::iterator です。

    std::vector<int> v = { 1, 2, 3};
    auto var = v.begin();
    auto キーワードを使用することにより、コードが読みやすくなり、記憶しにくい非基本型を記述しなくて済みます。

    ポインターは非基本型であることに注意してください。

  • 汎用ラムダ関数のパラメーターを宣言している。この関数は、関数テンプレートと同様に、複数種類のパラメーター型を受け入れることができます。たとえば、以下のコード スニペットの std::sort のカスタム実装は、int、float、その他の算術型のベクトルを並べ替えるために使用できます。

    //sort in ascending order
    std::sort(v.begin(), v.end(),
                  [](auto lhs, auto rhs){
                      return lhs < rhs});
    

  • 関数テンプレートを使用するため、後続の戻り値の型の構文を使用している。この場合、型の推定はありません。auto キーワードは、関数テンプレートの宣言に対する代替構文の一部として使用されています。以下のコード スニペットは、後続の戻り値の型の構文の例を示します。

    template<typename T, typename U>
    auto subtract(T lhs, U rhs) -> decltype(lhs - rhs);
    

Polyspace 実装

  • Polyspace® は、auto 指定子が前のセクションに示されているいずれかの用途以外で使用されている場合に、この指定子の使用にフラグを設定します。

  • Polyspace は、基本型の std::initializer_list で初期化される変数を宣言するための auto の使用にフラグを設定します。

  • Polyspace は decltype(auto) の使用にフラグを設定しません。

トラブルシューティング

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

すべて展開する

#include <string>
#include<vector>

auto func(int a)   // Non-compliant
{
    return a;
}

void func2()
{
    auto int_type = new int[5];           //  Non-compliant

    auto vector_type = std::vector<int> { 1, 2, 3 }; // Compliant

    const char* c = "hello";
    auto str2 =  std::string(c); // Compliant

    auto lambda = [](auto x, auto y) { // Compliant
        return x > y;
    };


}


この例では、func の戻り値の型の auto 指定子の使用は非準拠です。関数の推定される戻り値の型が明確ではない場合があります。同様に、int_type の宣言での auto の使用は非準拠です。この変数の初期化子は int 型の配列であり、基本型です。

この例での auto の他の使用は、このルールで指定された使用例に準拠しています。

  • vector_typestr2 の初期化子はそれぞれ非基本型の std::vector<int>stdd::string です (使用例 (2))。

  • 変数 lambda の初期化子は非基本型ラムダ式です (使用例 (2))。

  • 変数 xy はラムダ式のパラメーターです (使用例 (3))。

チェック情報

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

バージョン履歴

R2020b で導入