0

How can I get enum name associated with a int val.

I have following code:

   #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;
   }

The above code outputs the following: id is new_id1 3, new_id2 4, new_id3 3, new_id4 -1

Clearly, typecasting int to enum is dangerous. One way to resolve this is to use a function (like in the above) with switch statement to catch the invalid value passed. The issue with this is, I have really big enum with 100's of values so writing switch case for each enum is hectic task and not scalable approach. I would like to know if there is any efficient solution for the same.

prime130392
  • 133
  • 1
  • 2
  • 13

2 Answers2

0

If enums names is patterned (as in you sample), you can use macro for fast cases populating. For example, 101 cases can be simple populated

#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;
   }
}
Dmytro Dadyka
  • 2,208
  • 5
  • 18
  • 31
0

Underscore-beginning globals and especially underscore+uppercase-letter-beginning identifiers are reserved. If you must have both the tag and the typedef, just do typedef MyID { ...} MyID;.

As for your problem, if the enum constants are contiguously increasing, you can simply do:

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; }

Other than that there's always code generation. (If writing the program is tedious, write a program to write the program).

If you intend to assign -1 into the enum, you should probably make an enumerator constant for it too. Otherwise, the compiler might make MyID an unsigned type which might lead to a nasty surprise if you then ever do if (0>my_id).

Petr Skocik
  • 58,047
  • 6
  • 95
  • 142