MISRA 10.1者禁用的枚举类型的对象上执行算术。
基本上枚举类型的操作数不应该在算术运算,因为一个枚举对象使用实现定义整数类型一起使用。因此涉及一个枚举对象的操作可以产生一个意外类型的结果。需要注意的是从匿名枚举枚举常量基本上已经签署的类型。
他们还规定,++
和--
一元运算符为二进制加法和减法这一规则的目的处理。
如果我在循环控制结构使用整数我仍然需要投他们回来以后枚举,这将违反第10.5条
表达式的值不应该被强制转换为不合适的必要类型
有没有一种方法,我可以使用静态断言,以保证对基本枚举类型的一些假设?此代码可能会在未来的另一架构被重用。我想从10.5在这种情况下偏离有信心,该代码将抛出一个编译时错误,如果某些假设什么底层的枚举类型侵犯。
人为的例子:
enum {thing1, thing2, ... , thing_max } thing_index_t
...
for(int thing_index = 0; thing_index < (int) thing_max; ++thing_index)
{
init_something((thing_index_t) thing_index);
// ^~~~~~~~~~~~~~~~~~~~~~~~~
// cannot cast a signed value to an enum type
// [MISRA 2012 Rule 10.5, advisory]
}
这应该是一个安全的投如果我静态断言sizeof(thing_index_t == int);
和thing1 == 0u
吧?
诚信永远是大到足以容纳我的整个数值范围没有推广FWIW。
第10.5条为整体的声音,但是从enum
到签署控制转换/签名是没有危险的。 MISRAs值得关注的是,你可能有一个像enum {thing1=123, thing2=456, ...
枚举。但是,如果你知道枚举常量是从0到最大,它是那么大多是安全的去/从整数。
你并不需要咨询的规则正式偏差。我宁愿发表评论如
/* Violates MISRA 10.5 but iterating from thing1 to thing_num is safe.
Integer type is used since arithmetic on enums is forbidden by 10.1. */
(或使用任何过程中,你有地方处理咨询的规则。)
至于静态断言,sizeof(thing_index_t == int)
证明不了什么,因为不允许枚举常量的值是最重要的。而thing1 == 0u
是由C标准保证的,所以你不必断言。
静态断言,以确保枚举完整性而应像
#define THING_VALUES \
thing1, \
thing2, \
thing_num \
typedef enum { thing1=123, thing2=456, thing_num } thing_index_t;
const size_t expected_size = sizeof((thing_index_t[]){ THING_VALUES }) / sizeof(thing_index_t);
_Static_assert( thing_num+1 == expected_size );
其中化合物字面(thing_index_t[]){ THING_VALUES })
得到对应于在列表中的枚举常数的数量的大小。 expected_size
是项目的数量。此断言,没有什么特别的初始化如thing1=123
存在。
唯一循环孔是异国情调的东西像thing1=123, thing2=1
,此不着。为了防止这一点,你需要用宏走得更远,与X宏等。实现了整个事情