2

問題:

C で同じ enum 変数型に割り当てるときに enum 要素をキャストする必要があるのはなぜですか?

MISRA C 2012 ルール 10.3に失敗したため、このコードに問題がありました。

式の値は、より狭いエッセンシャル タイプまたは別のエッセンシャル タイプ カテゴリのオブジェクトに割り当てられません。

コードは次のとおりです。

typedef enum
{
   FLS_PROG_SUCCESS,
   FLS_PROG_FAIL,
   FLS_ERASE_SUCCESS2U,
   FLS_ERASE_FAIL,
   FLS_READ_SUCCESS,
   FLS_READ_FAIL,
   FLS_FORMAT_SUCCESS,
   FLS_FORMAT_FAIL
}FLS_JobResult_t;

void Foo(void)
{
   FLS_JobResult_t ProgramStatus;

   /* Then I try to initialize the variable value */
   ProgramStatus = FLS_PROG_SUCCESS;

   ...
}

そして、ツールに欠陥がある可能性があることを示唆する回答を受け入れました. 私はまだそれを信じていますが、それを修正しようとしてだまされて、現在の typedef enum 宣言に名前を付けました。

typedef enum FLS_JobResult_tag
{
   FLS_PROG_SUCCESS,
   FLS_PROG_FAIL,
   FLS_ERASE_SUCCESS2U,
   FLS_ERASE_FAIL,
   FLS_READ_SUCCESS,
   FLS_READ_FAIL,
   FLS_FORMAT_SUCCESS,
   FLS_FORMAT_FAIL
}FLS_JobResult_t;

そして、私が知る限り、両方ともまったく同じです。しかし、その後、驚き!エラーが消えました!ルール チェッカーはこれをエラーとしてフラグ付けしなくなりました!!

次に、いくつかの調査を行ったところ、次の2つの質問が見つかりました。

C でのこれら 2 つの typedef スタイルの違いは何ですか?

これら 2 つの enum 宣言の違いは何ですか - C?

そして、匿名の列挙型名前付きの列挙型には微妙な違いがあることに気付きました。しかし、ルール チェッカーが別の形式について不平を言う理由を明確にするものは何もありません。

問題は、MISRA c 2012 のルール 10.3 に違反する可能性のある匿名列挙型と名前付き列挙型の違いは何ですか?

4

4 に答える 4

3

どちらの例も準拠しており、理由は同じです。異なる必須タイプのオブジェクトを割り当て ていません。

混乱を解消しましょう。

C は、開発者/コンパイラにその型システムで多くの自由を与えますが、値、符号、または精度が失われる可能性があり、意図しない結果につながる可能性もあります。MISRA-C:2012 は、型変換の使用を制御し、実装固有の動作 (10.x 規則) の認識を促進する際の規則定義の合理的な基礎を提供する、その本質的な型モデルを使用して、より安全な型付けを強制するのに役立ちます。

エッセンシャル型モデルは、MISRA-C:2004 標準の「基礎となる型」モデル (1 つの理由で不必要なキャストを強制する多くのプログラマーの悲しみの原因となった) を置き換えます。

ツールが混乱しているか、古いモデルに部分的に固執していると思われます。

列挙型に関連する重要な型規則では、次の 2 つの異なるプログラミング用途が認識されます。

  1. 異なる列挙型を持つオブジェクトとは区別されるように意図された列挙型のオブジェクト。
  2. 列挙型は、一連の整数定数を保持する一般的な方法です。

C 標準では、これらの用途を区別する方法は提供されていません。したがって、MISRA-C:2012では、次の別個の必須の列挙型が追加されました (ただし、C の動作には影響しません)。

  1. 名前付き列挙型- これで定義された列挙型は、タグまたは typedef によって識別されるか、任意のオブジェクト、関数、または型の定義で使用されます。列挙定数の整数値が必要な場合は、キャストを使用する必要があります。
  2. 匿名列挙型- オブジェクト、関数、または型の定義で使用されない列挙。これは通常、関連する場合と関連しない場合がある一連の定数を定義するために使用されますが、キャストの必要はありません。

匿名列挙型の例:

enum {D = 10, E = 20, F = 30};

あなたの例はどちらも列挙型という名前です(そして、それらは同じ必須型であるため、準拠しています)。その他の例は次のとおりです。

enum JOHN {A, B, C};
enum PAUL {E, F, G} PAUL;

したがって、実際の 10.3 違反の例は次のようになります。

enum PAUL bar = B;

参照: MISRA-C:2012 付録 D.5「列挙の本質的なタイプ」は、他の例でこれを非常によく増幅します。

于 2015-08-11T04:25:46.540 に答える
3

左と右では、それが同じ匿名の列挙lside (type is anonymous enumeration) = rside (type is anonymous enumeration)であることを認識していないため、潜在的な問題があります。

- を使用lside (type is named enumeration) = rside (type is _same_ named enumeration)すると、同じ列挙が使用されることがわかっています。

于 2015-08-10T22:45:28.380 に答える