![](/img/trans.png)
[英]MISRA C-2012 Rule 10.3 violation due to adding of two 8 bit variables which resulted in 32 bit
[英]Why does an anonymous enum fails MISRA C 2012 rule 10.3 and a named enum doesn't?
问题:
在C中将其分配给相同的枚举变量类型时,为什么必须强制转换枚举元素?
我的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枚举声明中添加了一个名称 ,现在是:
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的匿名枚举和命名枚举有什么区别?
与lside (type is anonymous enumeration) = rside (type is anonymous enumeration)
左右不知道它是相同的匿名枚举-因此存在潜在的问题。
使用lside (type is named enumeration) = rside (type is _same_ named enumeration)
-一切正常,可以使用相同的枚举。
这两个示例都是兼容的,并且都是出于相同的原因:它们没有分配其他必需类型的对象。
让我们清除混乱。
C为开发人员/编译人员在其类型系统中赋予了很大的自由度,但它也可能导致意想不到的结果,并可能导致价值,符号或准确性的损失。 MISRA-C:2012通过其基本类型模型帮助强制执行更安全的键入,该模型为其规则定义提供了合理的基础,从而可以控制类型转换的使用并提高对实现特定行为的意识(10.x规则)。
基本类型模型替代了MISRA-C:2004标准的“基础类型”模型(由于一种原因,这引起了很多程序员对强制执行不必要的强制转换的悲伤)。
我怀疑您的工具很困惑,和/或部分卡在了旧型号上。
与枚举有关的基本类型规则识别两种不同的编程用途:
C标准没有提供区分这些用途的方法。 因此,MISRA-C:2012 添加了以下不同的基本枚举类型 (同时不影响C行为):
匿名枚举类型的示例:
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“枚举的基本类型”通过其他示例很好地放大了这一点。
真正的“错误”实际上在C标准(6.7.2.2)中。 C保证枚举常量的类型为int
,但是枚举变量可以是许多不同的类型,例如char
。
关于用于枚举常量和枚举变量的基本类型,在MISRA-C:2012附录D.6中进行了描述。 您代码中的枚举常量被认为与命名枚举类型具有相同的基本类型 。
因此该工具不正确,不应发出诊断信息。
(几乎)定义枚举始终是个坏主意。
最好编写如下:
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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.