Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conflicting enums

Tags:

c++

c

What happens if two different libs define the same enum and I need to use both libs in the same project?

enum Month {January=0, February, ..., December}

Thank you.

P.S. It is C. No namespaces. I won't be able to keep them separated. Need some workaround.

What it the enum linkage? Internal or external? C libs used in C++ project. C++ tag applies.

like image 737
pic11 Avatar asked Jun 08 '11 22:06

pic11


People also ask

Can two different enums have the same value?

Two enum names can have same value. For example, in the following C program both 'Failed' and 'Freezed' have same value 0.

Can two enums have the same name?

The body of an enum type declaration defines zero or more enum members, which are the named constants of the enum type. No two enum members can have the same name.

Can enums be overridden?

By default, the enum value is its method name. You can however override it, for example if you want to store enums as integers in a database, instead of using their method name. An enum value doesn't have to be a string, as you can see in the example.

Should enums go in header file?

Your code (e.g. your enum) SHOULD be placed in the . h file if you need to expose it to the code you're including the . h file. However if the enum is only specific to the code in your header's .


3 Answers

C libs used in C++ project. C++ tag applies

Since they're used in C++ projects, then you can use namespace when including them in C++ code as:

// C files
//libone.h 
enum Month {January=0, February, ..., December}

//libtwo.h
enum Month {January=0, February, ..., December}

///////////////////////////////////////////////////////////////////
//C++ files

//lib.hpp
namespace LibOne 
{
     #include "libone.h"
}
namespace LibTwo 
{
     #include "libtwo.h"
}

//Usage in C++
LibOne::Month m1 = LibOne::January;
LibTwo::Month m2 = LibTwo::January;
like image 110
Nawaz Avatar answered Sep 25 '22 21:09

Nawaz


Ultimate magic evil wizard workaround: if namespaces don't help (for whatever reason), and you absolutely can't avoid including both definitions in the same file, use a macro:

#define Month File_A_Month
#include "file_a.h"
#define Month File_B_Month
#include "file_b.h"
#undef Month

In the file, never use Month, only File_A_Month or File_B_Month. I'm not certain of the standards-correctness of this practice.

You might have to define all the enum members similarly to prevent clashes, and you probably want to put this evil hackery in a file called files_a_and_b.h. Of course, in your case the definitions are identical, so you shouldn't need to resort to this, but I'm leaving this answer here for less fortunate posterity.

like image 23
Chris Lutz Avatar answered Sep 22 '22 21:09

Chris Lutz


Neither the enum itself nor the enumeration constants are objects, so they don't have any linkage at all - in this respect, they're like struct tags or typedef names.

This means that you have two workarounds:

  • Ensure that the conflicting headers are never, directly or indirectly, #included in the same translation unit (.c file); or
  • Launder one or both of the headers to change the conflicting names.

The header laundering can be done either by creating a private copy of the header with the names changed, or using the preprocessor as in Chris Lutz's answer.

like image 25
caf Avatar answered Sep 21 '22 21:09

caf