Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use different enums that have the same names in C

Tags:

c

enums

I have in one library, liba, an enum like this:

typedef enum LIB_A_ENUM {
  FOO,
  BAR
} LIB_A_ENUM

In libb I have another enum:

typedef enum LIB_B_ENUM {
  FOO,
  BAR,
  BAZ // has a few different ones.
} LIB_B_ENUM

I would like to use both of them in libb like this:

int
some_function() {
  if (LIB_A_ENUM.FOO) {
    // ...
  } else if (LIB_B_ENUM.FOO) {
    // ...
  }
}

Wondering how to do that sort of thing. I'm imagining I should just create a bunch of global variables like:

LIB_A_ENUM LIB_A_ENUM_FOO = FOO;
LIB_A_ENUM LIB_A_ENUM_BAR = BAR;
// ...
LIB_B_ENUM LIB_B_ENUM_FOO = FOO;
LIB_B_ENUM LIB_B_ENUM_BAR = BAR;
LIB_B_ENUM LIB_B_ENUM_BAZ = BAZ;
// ...

int
some_function() {
  if (LIB_A_ENUM_FOO) {
    // ...
  } else if (LIB_B_ENUM_FOO) {
    // ...
  }    
}

Wondering if that is the sort of approach to do it, or if there is a better way.

Actually, I realize you can't even have two different enums with the same keys. So perhaps the best thing is to just have the enum values be globally unique. I'm not sure.

like image 852
Lance Avatar asked Nov 21 '25 11:11

Lance


2 Answers

You're right. Since the enum values are store in global scope, they have to be globally unique. The usual methods to prevent name collision in enum is to add the name enum's name as prefix for each of the enum values. It's kinda verbose but it should prevent errors in most cases.

typedef enum LIB_A_ENUM {
  LIB_A_ENUM_FOO,
  LIB_A_ENUM_BAR
} LIB_A_ENUM;

typedef enum LIB_B_ENUM {
  LIB_B_ENUM_FOO,
  LIB_B_ENUM_BAR,
  LIB_B_ENUM_BAZ
} LIB_B_ENUM;

like image 143
VietHTran Avatar answered Nov 23 '25 00:11

VietHTran


You can't. The C language requires that the names of enumeration constants do not clash with each other and other identifiers in the same scope. Not even global variables are going to help because you cannot #include the 2 headers at the same time...

So your choices boil down to:

  • change the enumeration constants so that they will have a prefix... (preferred!)

    • if you can't change the library headers, then perhaps you can #define a macro before inclusion of the clashing header, and #undef afterwards
  • don't use them in the same translation unit

  • or if you're really lucky, you can #include one of the headers within a function; the definition there wouldn't clash with the outer one.


Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!