pic11
pic11

Reputation: 14943

Conflicting enums

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.

Upvotes: 6

Views: 7481

Answers (5)

Enno
Enno

Reputation: 1862

Quote: I am writing C++ API and the same enum is already defined in my lib's namespace.

So one of these enums is inside the namespace of your library? Then you should not have a problem. The C library you are using is in the global namespace, your library has its own namespace, and as long as you do the Right Thing, the two will never collide. The following is perfectly valid, I believe:

extern "C" {
  #include "foo.h"
  // enum Month { January, February, December };
}

namespace mylib {
  enum Month { Chaos, Discord, Confusion, Bureaucracy, Aftermath };

  Month convert(::Month c_month);
}

void foo() {
  ::Month month = December;
  mylib::Month result = mylib::convert(month);
}

Upvotes: 0

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361352

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;

Upvotes: 12

Chris Lutz
Chris Lutz

Reputation: 75389

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.

Upvotes: 6

caf
caf

Reputation: 239021

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.

Upvotes: 4

Andy Thomas
Andy Thomas

Reputation: 86391

Ideally, the two are in different namespaces.

Otherwise, you may be able to avoid including both definitions in a single compile unit.

EDIT: Okay, you're in C, so you don't have namespaces, and it sounds like you want to reference both definitions in the same compile unit. Next steps:

  • Do they have exactly the same definition?
  • Do you have any influence on the names in either of the libraries?
  • Are you sure you can't hide references to one of them in a different compile unit?

Upvotes: 2

Related Questions