Staticly断言该枚举一定基本类型

问题描述 投票:2回答:1

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。

c enums c99 static-assert misra
1个回答
2
投票

第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宏等。实现了整个事情

© www.soinside.com 2019 - 2024. All rights reserved.