如何在C / C ++中具有多个相似值的枚举上切换()?

时间:2015-09-28 21:18:54

标签: c enums

让我们说我有一个枚举:

typedef enum
{
    gray = 4, //Gr[ae]y should be the same
    grey = 4,
    blue = 5,
    red  = 6
} FOO;

然后我想打开这个:

switch(f){
    case gray:
    case grey:
        printf("The color of an elephant\n"); break;
    case blue:
        printf("The color of the sky\n"); break;
    case red:
        printf("The color of an apple\n"); break;
    default:
        printf("I don't know this color\n"); 
 }

基本上我有枚举,其值基本上是我想以完全相同的方式处理的同义词。我尝试了上面的开关,但它并没有为我编译。有没有办法做到这一点,还是我坚持使用if / else逻辑? (我不是因为有20多个枚举,而且开关看起来更干净

编辑:是的,我知道我可以选择其中一个(并且没有区域设置不是解决方案),但是枚举明确允许您声明重复的值似乎有点奇怪然后不能在switch语句中使用它们?我想使用枚举,以便我可以在库API中静态强制执行它们发送正确的值(是的,我知道你可以绕过类型转换,我只是试图防止愚蠢的错误等等)。如果我这样做,现在看来我失去了在switch语句中使用它的能力。

编译器只是将逻辑简化为if / else逻辑。如果     案例4:     案例5:         酒吧();打破;

是合法的,为什么不能     案例4:     案例4:         酒吧();打破;

合法吗?编译器应该能够将其优化为一个语句并继续前进。

1 个答案:

答案 0 :(得分:7)

你不能。

C标准要求给定case语句的switch标签中的所有常量表达式具有不同的值。这在编译时检查。两个具有相同值的case标签是约束违规,需要编译时诊断。 (这可能是一个非致命的警告,但我不知道任何编译器都不会将其视为致命错误。)

规则在N1570 6.8.4.2p3:

中说明
  

每个 case 标签的表达式应为整数常量   表达式中没有两个 case 常量表达式    switch 语句在转换后应具有相同的值。

C ++有类似的规则。

这意味着,例如:

switch (blah) {
    case 2+2:
    case 4:
        /* ... */
}

也是非法的。编译器会检查表达式的,无论它们是否与人类读者有某些不同的含义。

您只需选择graygrey

(原则上,标准可以允许两个案例标签具有相同的值,只要它们组合在一起,就像在您的示例中一样。但它并非如此这样定义,可能是因为它没有被认为是有用的。)