一个C typedef枚举可以接受一个大于枚举中元素数量的值吗?

6tr1vspr  于 2023-03-01  发布在  其他
关注(0)|答案(2)|浏览(166)

我正在检查很多代码,看起来像这样

typedef enum {
    OPTION1
    OPTION2
} option_t

...

void a_function(option_t option){
    if(option == OPTION1){
        ...
    } else if(option == OPTION2){
        ...
    } else {
        // report an error!
        // can we ever get here?
    }
}

我的问题是,是否需要报告错误的else子句?在我看来,由于optionoption_t类型,一个只有两种可能性的枚举,所以option不可能有除OPTION1OPTION2之外的任何值,因此else子句应该永远不可能被执行。

vs3odd8k

vs3odd8k1#

枚举没有太多的类型安全性,通常会被设计类型破坏(到今天为止,即将到来的C23将改变许多C语言缺陷)。在您的示例中,OPTION1int类型,option_t是某个整数类型,它足够大,可以容纳枚举列表中的所有值,而不一定是int
我的问题是,是否需要报告错误的else子句?
这就是所谓的"防御性编程"。理论上,枚举不应该有任何其他值。实际上,没有什么可以阻止你给它赋值任何整数值。或者,在内存崩溃的情况下,也没有什么可以阻止bug将它更改为另一个值。
因此,这取决于您的需求。对于商业/业余爱好者/PC需求,可能不需要else。对于安全相关、关键任务或类似软件(例如MISRA C合规性),需要else,并且是良好的实践。
相关帖子:How to create type safe enums?

nbnkbykc

nbnkbykc2#

C标准对此并没有明确说明,但每个枚举类型实际上都是一些规则的整数类型,虽然C 2018 6. 12. 5 16说“...每个不同的枚举构成一个不同的 * 枚举类型 *",但6.7.2.24说“每个枚举类型都应该兼容char,一个有符号整数类型,或无符号整数类型。类型的选择由实现定义,但应能够表示枚举的所有成员的值...”
这两种方法都不清楚哪些值可以在枚举类型中表示,或者行为是否是为枚举的命名值之外的值定义的--说两种类型兼容并不是Assert一种类型的所有值都可以由另一种类型表示。

相关问题