7

列挙型を「署名なし」にする方法を見つけようとしています。

enum{
     x1 = 0,
     x2,
     x3
};
uint8_t = x2; /* <--- PC-LINT MISRA-C 2004 will complain about mixing signed and unsigned here */

もちろん、型キャストを追加してエラーを取り除くことができますが、これには時間がかかり、エラーが発生しやすくなります。

uint8_t = (uint8_t)x2; /* This works, but is a lot of extra work over the course of 1000s of lines of code*/

では、MISRA-C 2004 が好む特定の列挙型を署名なしにする方法はありますか?

4

5 に答える 5

11

に対して選択された型を制御する標準的な C の方法はありませんenum。型を強制的に符号なしにする値を列挙に追加するなど、実装固有の方法でそれを行うことができます。

enum {
  x1,
  x2,
  x3,
  giant_one_for_forcing_unsigned = 0x80000000;
};

しかし、それは標準の C でもありません (提供された値が に収まらないためint)。残念ながら、あなたはかなり運が悪いです。標準からの関連ビットは次のとおりです。

6.7.2.2 列挙指定子、パラグラフ 4

各列挙型はchar、符号付き整数型、または符号なし整数型と互換性があります。型の選択は実装定義ですが、列挙のすべてのメンバーの値を表すことができなければなりません。}列挙型は、列挙子宣言のリストを終了する の直後まで不完全であり、その後は完全です。

定数を作成する#defineよりも、使用した方がよい場合があります。enum

#define x1 0U
#define x2 1U
#define x3 2U

uint8_t x = x2;
于 2013-01-31T21:55:05.077 に答える
7

ここにはいくつかの懸念事項があり、MISRA が回避しようとしている変換バグの可能性がわずかにあります。

  • x1あなたの例では etc である列挙定数は、タイプint(1)であることが保証されています。ただし、enum変数と変数型 enum は同じ型であるとは限りません (2)。運が悪いと、短整数型として定義されるため、整数昇格規則が適用されます。

  • MISRA は、主に値の意図しない切り捨てを回避するためだけでなく、さまざまな暗黙的なプロモーション ルールを回避するために、大きな整数型から小さな整数型への暗黙的な変換を禁止しています。

特定のMISRAコンプライアンスエラーは、実際には上記の後者の懸念、ルール10.3(3)の違反に起因しています。

「基になる型」​​(意図した型) に明示的なキャストを追加することで、これを解決できます。この場合は、uint8_t へのキャストです。または、列挙型をまったく使用しないことで解決できます。それらを #defines に置き換えます。これは非常に過激に聞こえるかもしれませんが、C には型の安全性がまったくないことを覚えておいてください。

この方法で列挙型を置き換えることはやや一般的です。

#define FALSE 0
#define TRUE  1
typedef uint8_t BOOL;

(ただし、この例の目的は主に BOOL 型を移植可能にすることであり、列挙型の場合に発生する可能性があるように、8 ビットであり、決して 16 ビットではないことが保証されています。)


参考文献:

(1) C11 6.2.7.7/2:

「列挙定数の値を定義する式は、int として表現可能な値を持つ整数定数式でなければなりません。」

(2) C11 6.2.7.7/4:

「各列挙型は、char、符号付き整数型、または符号なし整数型と互換性があるものとします。型の選択は実装定義ですが、列挙型のすべてのメンバーの値を表すことができるものとします。」

(3) MISRA-c:2004 ルール 10.3:

「整数型の複雑な式の値は、式の基になる型と同じ符号の狭い型にのみキャストできます。」

于 2013-02-01T10:31:27.857 に答える
5

enumC90で unsigned 型を取ることを指定する方法がないだけでなく、C90 では次のようになります。

列挙定数として宣言された識別子の型は int です

これは、C99 (6.4.4.3) にも適用されます。署名されていない型が必要な場合は、言語拡張を見ています。

列挙型は以外でもかまいませintんが、定数自体にint型が必要です。

于 2013-01-31T22:02:41.087 に答える