获取与C中的int val关联的枚举名称。避免从int到枚举的类型转换

时间:2018-12-04 07:24:05

标签: c enums casting misra typecasting-operator

如何获取与int val关联的枚举名称。

我有以下代码:

   #include<stdio.h>
   #include<stdlib.h>


   typedef enum _MyID{
      id1 = 1,
      id2 = 2,
      id3 = 3,
   }MyID;

  MyID get_idname(int id_val)
  {
      switch(id_val){
         case 1:
            return id1;
         case 2:
            return id2;
         case 3:
            return id3;
         default:  //checks for invalid ID
            return -1;
      }
  }

   int main()
   {
       int val1 = 1;
       int val2 = 2;
       MyID new_id1 = (MyID)(val1|val2);
       MyID new_id2 = (MyID)(4);
       MyID new_id3 = get_idname(3);
       MyID new_id4 = get_idname(4);
       printf("id is new_id1 %d, new_id2 %d, new_id3 %d, new_id4 %d \n", new_id1, new_id2, new_id3, new_id4);

       return 0;
   }

上面的代码输出以下内容:         id为new_id1 3,new_id2 4,new_id3 3,new_id4 -1

很显然,将int类型转换为枚举是危险的。解决此问题的一种方法是使用带有switch语句的函数(如上)来捕获传递的无效值。问题是,我有一个很大的枚举,包含100个值,因此为每个枚举编写切换大小写是繁琐的任务,而不是可扩展的方法。我想知道是否有任何有效的解决方案。

2 个答案:

答案 0 :(得分:0)

如果枚举名称是带模式的(如您的示例中所示),则可以使用宏来快速填充个案。例如,可以简单地填充101个案例

#define CASE(N) case N: return id##N;
#define DOZEN_CASES(N) CASE(N##0) CASE(N##1) CASE(N##2) CASE(N##3) CASE(N##4) CASE(N##5)\
 CASE(N##6) CASE(N##7) CASE(N##8) CASE(N##9)

MyID get_idname(int id_val)
{
   switch (id_val) {
      DOZEN_CASES() DOZEN_CASES(1)
      DOZEN_CASES(2) DOZEN_CASES(3)
      DOZEN_CASES(4) DOZEN_CASES(5)
      DOZEN_CASES(6) DOZEN_CASES(7)
      DOZEN_CASES(8) DOZEN_CASES(9)
      CASE(100) CASE(101)
   default:  //checks for invalid ID
      return -1;
   }
}

答案 1 :(得分:0)

下划线开头的全局标识符,尤其是下划线+大写字母开头的标识符。如果必须同时包含标签和typedef,请执行typedef MyID { ...} MyID;

对于您的问题,如果枚举常量连续增加,则可以执行以下操作:

typedef enum MyID{
      idERR=-1,
      id1 = 1,
      id2 = 2,
      id3 = 3,
      //...
      idMAX
}MyID;
MyID get_idname(int id_val) { return (id_val>0&&id_val<idMAX)?id_val:-1; }

除此之外,总会有代码生成。 (如果编写程序很繁琐,请编写程序以编写程序。)

如果您打算将-1分配给enum,则可能也应该为其设置一个枚举数常量。否则,编译器可能会将MyID设置为无符号类型,如果您随后执行if (0>my_id),可能会导致令人讨厌的意外。