为什么匿名枚举不符合MISRA C 2012规则10.3,而命名枚举不';T
有关问题: 我因未通过MISRA C 2012第10.3条规则而对此代码有问题,该规则规定: 表达式的值不得分配给具有较窄基本类型或不同基本类型类别的对象 代码如下:为什么匿名枚举不符合MISRA C 2012规则10.3,而命名枚举不';T,c,enums,misra,error-checking,C,Enums,Misra,Error Checking,有关问题: 我因未通过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
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;
据我所知,两者完全相同。但是,惊喜错误消失了!规则检查器不再将其标记为错误
然后做了一些研究,我发现了两个问题:
及
我意识到,匿名枚举和命名枚举之间存在细微差别。但是,没有任何东西能够明确规则检查者抱怨一种形式的另一种形式的原因
因此,问题是:匿名枚举与命名枚举有什么区别,可能会违反MISRA c 2012的规则10.3?键入枚举(几乎)总是一个坏主意
最好是这样写:
enum FLS_JobResult_t
{
FLS_PROG_SUCCESS,
FLS_PROG_FAIL,
FLS_ERASE_SUCCESS2U,
FLS_ERASE_FAIL,
FLS_READ_SUCCESS,
FLS_READ_FAIL,
FLS_FORMAT_SUCCESS,
FLS_FORMAT_FAIL
};
void Foo(void)
{
enum FLS_JobResult_t ProgramStatus;
/* Then I try to initialize the variable value */
ProgramStatus = FLS_PROG_SUCCESS;
}
对于lside(类型为匿名枚举)=rside(类型为匿名枚举)
左右两侧不知道它是同一个匿名枚举,因此存在潜在问题
使用
lside(类型命名枚举)=rside(类型相同命名枚举)
-一切正常,已知使用了相同的枚举。两个示例都是兼容的,并且两个示例的原因相同:它们都没有指定不同基本类型的对象
让我们把困惑弄清楚
C在其类型系统中为开发人员/编译器提供了很多自由,但它也可能导致意外的结果,并可能导致值、符号或精度的损失。MISRA-C:2012通过其基本类型模型帮助实施更安全的类型,该模型为其规则定义提供了合理的基础,以控制类型转换的使用并提高对特定于实现的行为(10.x规则)的认识
基本类型模型取代了MISRA-C:2004标准的“底层类型”模型(由于一个原因,这导致了许多程序员执行不必要的强制转换)
我怀疑您的工具有误,和/或部分与旧型号卡住
与枚举相关的基本类型规则识别两种不同的编程用途:
enum JOHN {A, B, C};
enum PAUL {E, F, G} PAUL;
因此,实际10.3违规的一个例子是:
enum PAUL bar = B;
参考资料:MISRA-C:2012附录D.5“枚举的基本类型”与其他示例很好地放大了这一点。真正的“缺陷”实际上在C标准中(6.7.2.2).C保证枚举常量的类型为int
,但枚举变量可以是多种不同的类型,例如char
关于用于枚举常量和枚举变量的基本类型,请参见MISRA-C:2012附录D.6。代码中的枚举常量被视为与命名枚举类型相同的基本类型
因此,该工具不正确,不应发出诊断。这不应适用于ISO定义的标准C。它应在指定的标准中是特定的。.查找“基本类型”的MISRA定义。它与C中表达式的实际类型不同。只是一个观察:调试器(至少我使用过一些调试器)命名结构和未命名结构也有同样的问题。在内部,对象的类型似乎是由结构标记或枚举标记确定的,而typedef只是编译器使用的别名,而不是调试器或规则检查器使用的别名。@user3386109:我如何确定是否是这种情况?您能解释为什么不使用typede吗f它?它是否适用于
struct
s?你能详细说明一下吗?为什么它不好?typedef是结构、联合还是原语呢?这很好,但公司的一个编码规则是,所有结构和枚举都声明为typedef,然后用这些typedef创建变量来使用它们。@hustmrr:我同意,但有一个由许多人组成的团队,既有经验又不太多,这有助于防止人们做奇怪的事情,使代码看起来有点“标准化”,并有助于避免一些错误。这在某种程度上是好的。我不会(暂时)否决投票,但我很想知道你的理由……很高兴与你聊天()
enum PAUL bar = B;