ここにはいくつかの懸念事項があり、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:
「整数型の複雑な式の値は、式の基になる型と同じ符号の狭い型にのみキャストできます。」