Conflict Transfers

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

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

Thanks.

PS This is C. No namespaces. I cannot separate them. Some workaround is needed.

What is the enum connection? Internal or external? C libs used in a C ++ project. The C ++ tag is used.

+6
source share
5 answers

A workaround for a magical evil wizard: if namespaces do not help (for any reason), and you absolutely cannot 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 

Never use Month in a file, only File_A_Month or File_B_Month . I am not sure of the correctness of this practice.

You may need to define all the members of the enumeration in the same way as conflict prevention, and you probably want to put this evil hacker in a file called files_a_and_b.h . Of course, in your case the definitions are identical, so you do not need to resort to this, but I leave this answer here for less successful offspring.

+5
source

C libs used in a C ++ project. C ++ tag applied

Since they are used in C ++ projects, you can use the namespace when they are included in C ++ code as follows:

 // 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; 
+11
source

Neither enum itself nor the enumeration constants are objects, so they have no connection - in this respect, they are similar to struct or typedef tags.

This means that you have two workarounds:

  • Make sure that conflicting headers are never, directly or indirectly, #include d in the same translation system ( .c file); or
  • Send one or both headers to change conflicting names.

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

+4
source

Ideally, they are in different namespaces.

Otherwise, you can avoid including both definitions in a single compilation unit.

EDIT : Well, you're in C, so you don't have namespaces, and it looks like you want to reference both definitions in the same compiler. Next steps:

  • Do they have exactly the same definition?
  • Do you have any influence on the names in any of the libraries?
  • Are you sure you cannot hide links to one of them in another compiler?
+2
source

Quote: I am writing a C ++ API, and the same enumeration is already defined in my lib namespace.

So, one of these enumerations is inside the namespace of your library? Then you should not have a problem. The C library that you use is in the global namespace, your library has its own namespace, and as long as you do the right thing, they will never come across. The following is quite fair, 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); } 
0
source

Source: https://habr.com/ru/post/890098/


All Articles